Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
2011-09-02 10:58
423 查看
Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
背景(只是个人感想,技术上不对后面的内容构成知识性障碍,可以skip):
最近,基于某些原因和需要,笔者需要去了解一下Crypto++库,然后对一些数据进行一些加密解密的操作。
笔者之前没接触过任何加密解密方面的知识(当然,把每个字符的ASCII值加1之流对明文进行加密的“趣事”还是干过的,当时还很乐在其中。),甚至一开始连Crypto++的名字都没有听过,被BS了之后,就开始了Crypto++的入门探索过程。
最初,大概知道了要了解两大类算法中的几个算法——对称加密算法:DES、AES(后来因为人品好的缘故也了解了下非对称加密算法RSA,后文会详述何谓“人品好”);散列算法(需要通过Hash运算):SHA-256。
起初,笔者以为这样的知名算法在网上应该有很多现成的例子。笔者比较懒,对于自己不熟悉的东西,总希望找捷径,直接找别人现(在已经写)成可(编译运)行的代码然后施展ctrl + C,ctrl + V算法(咳,什么算法,是大法!!!)。
However,发觉网上的例子不是稀缺,就是只有代码没有解释。笔者觉得很难忍受这样的“莫名其妙”(奇怪的是笔者容忍了windows了,尽管它不开源),遂决定从零开始……
……写在代码前……
如果之前像笔者一样没相关经验——完全没接触过加密解密——,请务必阅读下文。
一些前期工作——编译cryptlib并使其可用:
本文不涉及这部分内容,因为已经有相对完善的资料:
http://www.cnblogs.com/cxun/archive/2008/07/30/743541.html
总结了一点预备知识:
关于几个算法的介绍,网上各大百科都有,笔者不再详细Ctrl+C/V了。不过在写代码之前,即使复制修改人家代码之前,也有必要了解一下几个算法(除了名称之外)的使用流程(不是算法具体的实现,汗!)。
对称加密:(AES、DES)
相对于与非对称加密而言,加密、解密用的密匙相同。就像日常生活中的钥匙,开门和锁门都是同一把。
详见:http://baike.baidu.com/view/119320.htm
非对称加密:(RSA)
相对于上述的对称加密而言,加密、解密用的密匙不同,有公匙和私匙之分。
详见:http://baike.baidu.com/view/554866.htm
散列算法:(SHA系列,我们熟悉的MD5等)
用途:验证信息有没有被修改。
原理:对长度大的信息进行提炼(通过一个Hash函数),提炼过后的信息长度小很多,得到的是一个固定长度的值(Hash值)。对于两个信息量很大的文件通过比较这两个值,就知道这两个文件是否完全一致(另外一个文件有没有被修改)。从而避免了把两个文件中的信息进行逐字逐句的比对,减少时间开销。
形象地描述:鬼泣3里面维吉尔跟但丁除了发型之外都很像。怎么区分两个双生子?比较他们的DNA就好比是比较信息量很大的文件,然而直接看发型就好比是看Hash值。一眼就看出来了。
注:以上是笔者对几个概念的,非常不严格的,非常主观的,概括的描述,想要详细了解,可以:
http://wenku.baidu.com/view/4fb8e0791711cc7931b716aa.html
几个算法的介绍,选择,比较。
……Code speaking……
平台:WindowsXP
IDE以及工具:Visual Studio 2008 + Visual Assist
库版本:Crypto++ 5.6.0
库的文档(包括类和函数的接口列表):
http://www.cryptopp.com/docs/ref/index.html
对称加密算法:
DES:
一开始笔者并没有找到关于DES运用的很好的例程,或者说,笔者的搜索功力薄弱,未能找到非常完整的例程吧。
http://bbs.pediy.com/showthread.php?p=745389
笔者以下的代码主要是参考上面URL的论坛回帖,但是作了些修改:
1
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <iostream>
2
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <des.h>
3
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
4
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#pragma comment( lib, "cryptlib.lib" )
5
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
6
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
7
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace CryptoPP;
8
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
9
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int main( void )
10
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
11
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//主要是打印一些基本信息,方便调试:
12
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "DES Parameters: " << endl;
13
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Algorithm name : " << DES::StaticAlgorithmName() << endl;
14
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
15
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char key[ DES::DEFAULT_KEYLENGTH ];
16
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char input[ DES::BLOCKSIZE ] = "12345";
17
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char output[ DES::BLOCKSIZE ];
18
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char txt[ DES::BLOCKSIZE ];
19
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
20
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "input is: " << input << endl;
21
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
22
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//可以理解成首先构造一个加密器
23
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
DESEncryption encryption_DES;
24
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
25
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//回忆一下之前的背景,对称加密算法需要一个密匙。加密和解密都会用到。
26
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//因此,设置密匙。
27
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
encryption_DES.SetKey( key, DES::KEYLENGTH );
28
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//进行加密
29
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
encryption_DES.ProcessBlock( input, output );
30
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
31
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//显示结果
32
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//for和for之后的cout可有可无,主要为了运行的时候看加密结果
33
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//把字符串的长度写成一个常量其实并不被推荐。
34
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//不过笔者事先知道字符串长,为了方便调试,就直接写下。
35
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//这里主要是把output也就是加密后的内容,以十六进制的整数形式输出。
36
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for( int i = 0; i < 5; i++ )
37
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
38
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << hex << (int)output[ i ] << ends;
39
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
40
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << endl;
41
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
42
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//构造一个加密器
43
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
DESDecryption decryption_DES;
44
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
45
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//由于对称加密算法的加密和解密都是同一个密匙,
46
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//因此解密的时候设置的密匙也是刚才在加密时设置好的key
47
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
decryption_DES.SetKey( key, DES::KEYLENGTH );
48
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//进行解密,把结果写到txt中
49
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//decryption_DES.ProcessAndXorBlock( output, xorBlock, txt );
50
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
decryption_DES.ProcessBlock( output, txt );
51
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
52
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//以上,加密,解密还原过程已经结束了。以下是为了验证:
53
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//加密前的明文和解密后的译文是否相等。
54
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( memcmp( input, txt, 5 ) != 0 )
55
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
56
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cerr << "DES Encryption/decryption failed.\n";
57
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
abort();
58
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
59
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "DES Encryption/decryption succeeded.\n";
60
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
61
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
62
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
63
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
回想一下以上代码的编写过程,就可以发现,进行DES加密,流程大概是:
数据准备;
构造加密器;
设置加密密匙;
加密数据;
显示(非必要);
设置解密密匙(跟加密密匙是同一个key);
解密数据;
验证与显示(非必要);
由此可见,主要函数的调用流程就是这样。但是文档没有详细讲,笔者当时打开下载回来的源文件时,就傻了眼。
猜想:
AES和以后的算法,是不是都是按照这些基本的套路呢?
AES:
在实际运用的时候,从代码上看,AES跟DES非常相像。但是值得注意一点的是,AES取代了DES成为21世纪的加密标准。是因为以其密匙长度和高安全性获得了先天优势。虽然界面上看上去没多大区别,但是破解难度远远大于DES。详细情况,在之前的URL有提及过。
很幸运,笔者很快就找到了AES的使用例程,而且很详细:
http://dev.firnow.com/course/3_program/c++/cppsl/2008827/138033.html
1
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <iostream>
2
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <aes.h>
3
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
4
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#pragma comment( lib, "cryptlib.lib" )
5
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
6
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
7
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace CryptoPP;
8
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
9
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int main()
10
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
11
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
12
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//AES中使用的固定参数是以类AES中定义的enum数据类型出现的,而不是成员函数或变量
13
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//因此需要用::符号来索引
14
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "AES Parameters: " << endl;
15
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Algorithm name : " << AES::StaticAlgorithmName() << endl;
16
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
17
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//Crypto++库中一般用字节数来表示长度,而不是常用的字节数
18
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Block size : " << AES::BLOCKSIZE * 8 << endl;
19
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Min key length : " << AES::MIN_KEYLENGTH * 8 << endl;
20
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Max key length : " << AES::MAX_KEYLENGTH * 8 << endl;
21
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
22
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//AES中只包含一些固定的数据,而加密解密的功能由AESEncryption和AESDecryption来完成
23
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//加密过程
24
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
AESEncryption aesEncryptor; //加密器
25
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
26
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char aesKey[AES::DEFAULT_KEYLENGTH]; //密钥
27
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char inBlock[AES::BLOCKSIZE] = "123456789"; //要加密的数据块
28
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char outBlock[AES::BLOCKSIZE]; //加密后的密文块
29
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char xorBlock[AES::BLOCKSIZE]; //必须设定为全零
30
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
31
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
memset( xorBlock, 0, AES::BLOCKSIZE ); //置零
32
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
33
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
aesEncryptor.SetKey( aesKey, AES::DEFAULT_KEYLENGTH ); //设定加密密钥
34
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
aesEncryptor.ProcessAndXorBlock( inBlock, xorBlock, outBlock ); //加密
35
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
36
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//以16进制显示加密后的数据
37
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
for( int i=0; i<16; i++ )
![](http://www.cppblog.com/Images/dot.gif)
{
38
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << hex << (int)outBlock[i] << " ";
39
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
40
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << endl;
41
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
42
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//解密
43
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
AESDecryption aesDecryptor;
44
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char plainText[AES::BLOCKSIZE];
45
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
46
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
aesDecryptor.SetKey( aesKey, AES::DEFAULT_KEYLENGTH );
47
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//细心的朋友注意到这里的函数不是之前在DES中出现过的:ProcessBlock,
48
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//而是多了一个Xor。其实,ProcessAndXorBlock也有DES版本。用法跟AES版本差不多。
49
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//笔者分别在两份代码中列出这两个函数,有兴趣的朋友可以自己研究一下有何差异。
50
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
aesDecryptor.ProcessAndXorBlock( outBlock, xorBlock, plainText );
51
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
52
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
53
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for( int i=0; i<16; i++ )
54
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
55
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << plainText[i];
56
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
57
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << endl;
58
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
59
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
60
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
61
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
62
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
其实来到这里,都可以发现,加密解密的套路也差不多,至于之后笔者在误打误撞中找到的RSA,也只不过是在设置密匙的时候多了私匙和公匙的区别而已。笔者总觉得,有完整的例程对照学习,是一件很幸福的事情。
非对称加密算法:
RSA:
小背景:
其实,笔者在一开始并没有接到“了解RSA”的要求。不过由于笔者很粗心,在看AES的时候只记得A和S两个字母,Google的时候就误打误撞Google了一个RSA。其实RSA方面的资料还是挺多的,因此它事实上是笔者第一个编译运行成功的Crypto++库中算法的应用实例。
http://www.cnblogs.com/cxun/archive/2008/07/30/743541.html
以下代码主要是按照上述URL中提供的代码写成的,作为笔者的第一份有效学习资料,笔者认为作为调用者的我们,不用清楚算法实现的细节。只需要明白几个主要函数的功用和调用的次序即可。
由以下代码可以看出,其实RSA也离不开:数据准备、设置密匙(注意,有公匙和私匙)、加密解密这样的套路。至于如何产生密匙,有兴趣的朋友可以到Crypto++的主页上下载源文件研究。作为入门和了解阶段,笔者觉得:只需要用起来即可。
1
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//version at Crypto++ 5.60
2
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "randpool.h"
3
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "rsa.h"
4
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "hex.h"
5
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "files.h"
6
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <iostream>
7
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
8
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
9
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace CryptoPP;
10
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
11
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#pragma comment(lib, "cryptlib.lib")
12
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
13
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
14
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
15
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
16
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 函数声明
17
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
18
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
19
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
20
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void GenerateRSAKey( unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed );
21
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
string RSAEncryptString( const char *pubFilename, const char *seed, const char *message );
22
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
string RSADecryptString( const char *privFilename, const char *ciphertext );
23
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
RandomPool & GlobalRNG();
24
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
25
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
26
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 主程序
27
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
28
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
29
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void main( void )
30
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
31
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
32
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
char priKey[ 128 ] =
![](http://www.cppblog.com/Images/dot.gif)
{ 0 };
33
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
char pubKey[ 128 ] =
![](http://www.cppblog.com/Images/dot.gif)
{ 0 };
34
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
char seed[ 1024 ] =
![](http://www.cppblog.com/Images/dot.gif)
{ 0 };
35
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
36
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// 生成 RSA 密钥对
37
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy( priKey, "pri" ); // 生成的私钥文件
38
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy( pubKey, "pub" ); // 生成的公钥文件
39
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy( seed, "seed" );
40
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
GenerateRSAKey( 1024, priKey, pubKey, seed );
41
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
42
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// RSA 加解密
43
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
char message[ 1024 ] =
![](http://www.cppblog.com/Images/dot.gif)
{ 0 };
44
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout<< "Origin Text:\t" << "Hello World!" << endl << endl;
45
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy( message, "Hello World!" );
46
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string encryptedText = RSAEncryptString( pubKey, seed, message ); // RSA 公匙加密
47
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout<<"Encrypted Text:\t"<< encryptedText << endl << endl;
48
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string decryptedText = RSADecryptString( priKey, encryptedText.c_str() ); // RSA 私匙解密
49
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
50
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
51
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
52
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
53
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
54
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
55
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 生成RSA密钥对
56
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
57
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
58
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
59
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
60
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
61
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RandomPool randPool;
62
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
randPool.Put((byte *)seed, strlen(seed));
63
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
64
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
65
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
HexEncoder privFile(new FileSink(privFilename));
66
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
67
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
priv.DEREncode(privFile);
68
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
privFile.MessageEnd();
69
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
70
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RSAES_OAEP_SHA_Encryptor pub(priv);
71
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
HexEncoder pubFile(new FileSink(pubFilename));
72
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
pub.DEREncode(pubFile);
73
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
74
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
pubFile.MessageEnd();
75
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
76
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ;
77
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
78
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
79
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
80
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
81
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
82
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
83
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// RSA加密
84
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
85
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
86
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
87
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
string RSAEncryptString( const char *pubFilename, const char *seed, const char *message )
88
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
89
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
FileSource pubFile( pubFilename, true, new HexDecoder );
90
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RSAES_OAEP_SHA_Encryptor pub( pubFile );
91
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
92
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RandomPool randPool;
93
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
randPool.Put( (byte *)seed, strlen(seed) );
94
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
95
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string result;
96
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
StringSource( message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))) );
97
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
98
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return result;
99
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
100
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
101
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
102
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
103
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
104
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// RSA解密
105
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
106
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
107
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
string RSADecryptString( const char *privFilename, const char *ciphertext )
108
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
109
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
FileSource privFile( privFilename, true, new HexDecoder );
110
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RSAES_OAEP_SHA_Decryptor priv(privFile);
111
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
112
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string result;
113
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
StringSource( ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))) );
114
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
115
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return result;
116
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
117
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
118
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
119
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
120
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
121
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
122
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 定义全局的随机数池
123
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
124
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
125
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
126
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
RandomPool & GlobalRNG()
127
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
128
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
static RandomPool randomPool;
129
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return randomPool;
130
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
131
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
132
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
散列算法:
SHA-256
SHA-256主要是用来求一大段信息的Hash值,跟之前三个用于加密、解密的算法有所不同。用到SHA的场合,多半是为了校验文件。
笔者的参考资料:http://hi.baidu.com/magic475/blog/item/19b37a8c1fa15a14b21bbaeb.html
请注意,笔者在实现的时候,稍微修改了一下两个子函数的实现,以满足笔者的需求。因此会与上述URL中的代码有差异。
1
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//http://hi.baidu.com/magic475/blog/item/19b37a8c1fa15a14b21bbaeb.html
2
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <iostream>
3
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <string.h>
4
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
5
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "sha.h"
6
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "secblock.h"
7
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "modes.h"
8
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "hex.h"
9
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
10
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#pragma comment( lib, "cryptlib.lib")
11
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
12
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
13
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace CryptoPP;
14
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
15
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void CalculateDigest(string &Digest, const string &Message);
16
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
bool VerifyDigest(const string &Digest, const string &Message);
17
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
18
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int main( void )
19
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
20
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//main函数中注释掉的,关于strMessage2的代码,其实是笔者模拟了一下
21
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//通过求Hash值来对“大”量数据进行校验的这个功能的运用。
22
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//注释之后并不影响这段代码表达的思想和流程。
23
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string strMessage( "Hello world" );
24
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string strDigest;
25
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//string strMessage2( "hello world" ); //只是第一个字母不同
26
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//string strDigest2;
27
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
28
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
CalculateDigest( strDigest, strMessage ); //计算Hash值并打印一些debug信息
29
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "the size of Digest is: " << strDigest.size() << endl;
30
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Digest is: " << strDigest << endl;
31
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
32
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//CalculateDigest( strDigest2, strMessage2 );
33
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//why put this function here will affect the Verify function?
34
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//作者在写代码的过程中遇到的上述问题。
35
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//如果把这行代码的注释取消,那么之后的运行结果就不是预料中的一样:
36
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//即使strDigest也无法对应strMessage,笔者不知道为什么,希望高手指出,谢谢!
37
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
38
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
bool bIsSuccess = false;
39
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
bIsSuccess = VerifyDigest( strDigest, strMessage );
40
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//通过校验,看看strDigest是否对应原来的message
41
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( bIsSuccess )
42
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
43
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "sussessive verify" << endl;
44
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "origin string is: " << strMessage << endl << endl;
45
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
46
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else
47
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
48
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "fail!" << endl;
49
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
50
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
51
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//通过strDigest2与strMessage进行校验,要是相等,
52
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//就证明strDigest2是对应的strMessage2跟strMessage1相等。
53
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//否则,像这个程序中的例子一样,两个message是不相等的
54
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
/**//*CalculateDigest( strDigest2, strMessage2 );
55
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
bIsSuccess = VerifyDigest( strDigest2, strMessage );
56
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( !bIsSuccess )
57
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
{
58
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "success! the tiny modification is discovered~" << endl;
59
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "the origin message is: \n" << strMessage << endl;
60
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "after modify is: \n" << strMessage2 << endl;
61
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}*/
62
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
63
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
64
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
65
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
66
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//基于某些原因,以下两个子函数的实现跟原来参考代码中的实现有所区别,
67
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//详细原因,笔者在CalculateDigest函数的注释中写明
68
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void CalculateDigest(string &Digest, const string &Message)
69
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
70
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
SHA256 sha256;
71
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int DigestSize = sha256.DigestSize();
72
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
char* byDigest;
73
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
char* strDigest;
74
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
75
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
byDigest = new char[ DigestSize ];
76
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strDigest = new char[ DigestSize * 2 + 1 ];
77
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
78
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
sha256.CalculateDigest((byte*)byDigest, (const byte *)Message.c_str(), Message.size());
79
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
memset(strDigest, 0, sizeof(strDigest));
80
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//uCharToHex(strDigest, byDigest, DigestSize);
81
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//参考的代码中有以上这么一行,但是貌似不是什么库函数。
82
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//原作者大概是想把Hash值转换成16进制数保存到一个string buffer中,
83
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//然后在主程序中输出,方便debug的时候对照查看。
84
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//但是这并不影响计算Hash值的行为。
85
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//因此笔者注释掉了这行代码,并且修改了一下这个函数和后面的VerifyDigest函数,
86
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//略去原作者这部分的意图,继续我们的程序执行。
87
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
88
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
Digest = byDigest;
89
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
90
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
delete []byDigest;
91
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
byDigest = NULL;
92
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
delete []strDigest;
93
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strDigest = NULL;
94
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
95
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return;
96
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
97
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
98
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
bool VerifyDigest(const string &Digest, const string &Message)
99
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
100
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
bool Result;
101
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
SHA256 sha256;
102
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
char* byDigest;
103
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
104
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
byDigest = new char[ sha256.DigestSize() ];
105
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy( byDigest, Digest.c_str() );
106
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
107
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//HexTouChar(byDigest, Digest.c_str(), Digest.size());
108
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//为何注释掉,请参看CalculateDigest函数的注释
109
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
Result = sha256.VerifyDigest( (byte*)byDigest, (const byte *)Message.c_str(), Message.size() );
110
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
111
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
delete []byDigest;
112
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
byDigest = NULL;
113
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return Result;
114
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
115
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
116
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
后记:
为什么写这篇文章呢?因为笔者在搜索过程中觉得这方面的资料有点分散,因此想把它们集中起来,方便刚刚入门的朋友。
同时,也算是为自己留点学习资料吧。
背景(只是个人感想,技术上不对后面的内容构成知识性障碍,可以skip):
最近,基于某些原因和需要,笔者需要去了解一下Crypto++库,然后对一些数据进行一些加密解密的操作。
笔者之前没接触过任何加密解密方面的知识(当然,把每个字符的ASCII值加1之流对明文进行加密的“趣事”还是干过的,当时还很乐在其中。),甚至一开始连Crypto++的名字都没有听过,被BS了之后,就开始了Crypto++的入门探索过程。
最初,大概知道了要了解两大类算法中的几个算法——对称加密算法:DES、AES(后来因为人品好的缘故也了解了下非对称加密算法RSA,后文会详述何谓“人品好”);散列算法(需要通过Hash运算):SHA-256。
起初,笔者以为这样的知名算法在网上应该有很多现成的例子。笔者比较懒,对于自己不熟悉的东西,总希望找捷径,直接找别人现(在已经写)成可(编译运)行的代码然后施展ctrl + C,ctrl + V算法(咳,什么算法,是大法!!!)。
However,发觉网上的例子不是稀缺,就是只有代码没有解释。笔者觉得很难忍受这样的“莫名其妙”(奇怪的是笔者容忍了windows了,尽管它不开源),遂决定从零开始……
……写在代码前……
如果之前像笔者一样没相关经验——完全没接触过加密解密——,请务必阅读下文。
一些前期工作——编译cryptlib并使其可用:
本文不涉及这部分内容,因为已经有相对完善的资料:
http://www.cnblogs.com/cxun/archive/2008/07/30/743541.html
总结了一点预备知识:
关于几个算法的介绍,网上各大百科都有,笔者不再详细Ctrl+C/V了。不过在写代码之前,即使复制修改人家代码之前,也有必要了解一下几个算法(除了名称之外)的使用流程(不是算法具体的实现,汗!)。
对称加密:(AES、DES)
相对于与非对称加密而言,加密、解密用的密匙相同。就像日常生活中的钥匙,开门和锁门都是同一把。
详见:http://baike.baidu.com/view/119320.htm
非对称加密:(RSA)
相对于上述的对称加密而言,加密、解密用的密匙不同,有公匙和私匙之分。
详见:http://baike.baidu.com/view/554866.htm
散列算法:(SHA系列,我们熟悉的MD5等)
用途:验证信息有没有被修改。
原理:对长度大的信息进行提炼(通过一个Hash函数),提炼过后的信息长度小很多,得到的是一个固定长度的值(Hash值)。对于两个信息量很大的文件通过比较这两个值,就知道这两个文件是否完全一致(另外一个文件有没有被修改)。从而避免了把两个文件中的信息进行逐字逐句的比对,减少时间开销。
形象地描述:鬼泣3里面维吉尔跟但丁除了发型之外都很像。怎么区分两个双生子?比较他们的DNA就好比是比较信息量很大的文件,然而直接看发型就好比是看Hash值。一眼就看出来了。
注:以上是笔者对几个概念的,非常不严格的,非常主观的,概括的描述,想要详细了解,可以:
http://wenku.baidu.com/view/4fb8e0791711cc7931b716aa.html
几个算法的介绍,选择,比较。
……Code speaking……
平台:WindowsXP
IDE以及工具:Visual Studio 2008 + Visual Assist
库版本:Crypto++ 5.6.0
库的文档(包括类和函数的接口列表):
http://www.cryptopp.com/docs/ref/index.html
对称加密算法:
DES:
一开始笔者并没有找到关于DES运用的很好的例程,或者说,笔者的搜索功力薄弱,未能找到非常完整的例程吧。
http://bbs.pediy.com/showthread.php?p=745389
笔者以下的代码主要是参考上面URL的论坛回帖,但是作了些修改:
1
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <iostream>
2
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <des.h>
3
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
4
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#pragma comment( lib, "cryptlib.lib" )
5
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
6
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
7
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace CryptoPP;
8
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
9
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int main( void )
10
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
11
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//主要是打印一些基本信息,方便调试:
12
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "DES Parameters: " << endl;
13
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Algorithm name : " << DES::StaticAlgorithmName() << endl;
14
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
15
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char key[ DES::DEFAULT_KEYLENGTH ];
16
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char input[ DES::BLOCKSIZE ] = "12345";
17
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char output[ DES::BLOCKSIZE ];
18
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char txt[ DES::BLOCKSIZE ];
19
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
20
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "input is: " << input << endl;
21
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
22
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//可以理解成首先构造一个加密器
23
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
DESEncryption encryption_DES;
24
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
25
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//回忆一下之前的背景,对称加密算法需要一个密匙。加密和解密都会用到。
26
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//因此,设置密匙。
27
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
encryption_DES.SetKey( key, DES::KEYLENGTH );
28
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//进行加密
29
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
encryption_DES.ProcessBlock( input, output );
30
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
31
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//显示结果
32
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//for和for之后的cout可有可无,主要为了运行的时候看加密结果
33
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//把字符串的长度写成一个常量其实并不被推荐。
34
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//不过笔者事先知道字符串长,为了方便调试,就直接写下。
35
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//这里主要是把output也就是加密后的内容,以十六进制的整数形式输出。
36
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for( int i = 0; i < 5; i++ )
37
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
38
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << hex << (int)output[ i ] << ends;
39
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
40
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << endl;
41
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
42
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//构造一个加密器
43
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
DESDecryption decryption_DES;
44
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
45
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//由于对称加密算法的加密和解密都是同一个密匙,
46
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//因此解密的时候设置的密匙也是刚才在加密时设置好的key
47
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
decryption_DES.SetKey( key, DES::KEYLENGTH );
48
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//进行解密,把结果写到txt中
49
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//decryption_DES.ProcessAndXorBlock( output, xorBlock, txt );
50
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
decryption_DES.ProcessBlock( output, txt );
51
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
52
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//以上,加密,解密还原过程已经结束了。以下是为了验证:
53
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//加密前的明文和解密后的译文是否相等。
54
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( memcmp( input, txt, 5 ) != 0 )
55
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
56
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cerr << "DES Encryption/decryption failed.\n";
57
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
abort();
58
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
59
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "DES Encryption/decryption succeeded.\n";
60
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
61
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
62
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
63
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
回想一下以上代码的编写过程,就可以发现,进行DES加密,流程大概是:
数据准备;
构造加密器;
设置加密密匙;
加密数据;
显示(非必要);
设置解密密匙(跟加密密匙是同一个key);
解密数据;
验证与显示(非必要);
由此可见,主要函数的调用流程就是这样。但是文档没有详细讲,笔者当时打开下载回来的源文件时,就傻了眼。
猜想:
AES和以后的算法,是不是都是按照这些基本的套路呢?
AES:
在实际运用的时候,从代码上看,AES跟DES非常相像。但是值得注意一点的是,AES取代了DES成为21世纪的加密标准。是因为以其密匙长度和高安全性获得了先天优势。虽然界面上看上去没多大区别,但是破解难度远远大于DES。详细情况,在之前的URL有提及过。
很幸运,笔者很快就找到了AES的使用例程,而且很详细:
http://dev.firnow.com/course/3_program/c++/cppsl/2008827/138033.html
1
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <iostream>
2
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <aes.h>
3
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
4
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#pragma comment( lib, "cryptlib.lib" )
5
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
6
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
7
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace CryptoPP;
8
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
9
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int main()
10
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
11
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
12
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//AES中使用的固定参数是以类AES中定义的enum数据类型出现的,而不是成员函数或变量
13
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//因此需要用::符号来索引
14
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "AES Parameters: " << endl;
15
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Algorithm name : " << AES::StaticAlgorithmName() << endl;
16
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
17
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//Crypto++库中一般用字节数来表示长度,而不是常用的字节数
18
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Block size : " << AES::BLOCKSIZE * 8 << endl;
19
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Min key length : " << AES::MIN_KEYLENGTH * 8 << endl;
20
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Max key length : " << AES::MAX_KEYLENGTH * 8 << endl;
21
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
22
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//AES中只包含一些固定的数据,而加密解密的功能由AESEncryption和AESDecryption来完成
23
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//加密过程
24
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
AESEncryption aesEncryptor; //加密器
25
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
26
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char aesKey[AES::DEFAULT_KEYLENGTH]; //密钥
27
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char inBlock[AES::BLOCKSIZE] = "123456789"; //要加密的数据块
28
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char outBlock[AES::BLOCKSIZE]; //加密后的密文块
29
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char xorBlock[AES::BLOCKSIZE]; //必须设定为全零
30
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
31
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
memset( xorBlock, 0, AES::BLOCKSIZE ); //置零
32
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
33
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
aesEncryptor.SetKey( aesKey, AES::DEFAULT_KEYLENGTH ); //设定加密密钥
34
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
aesEncryptor.ProcessAndXorBlock( inBlock, xorBlock, outBlock ); //加密
35
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
36
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//以16进制显示加密后的数据
37
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
for( int i=0; i<16; i++ )
![](http://www.cppblog.com/Images/dot.gif)
{
38
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << hex << (int)outBlock[i] << " ";
39
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
40
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << endl;
41
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
42
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//解密
43
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
AESDecryption aesDecryptor;
44
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
unsigned char plainText[AES::BLOCKSIZE];
45
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
46
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
aesDecryptor.SetKey( aesKey, AES::DEFAULT_KEYLENGTH );
47
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//细心的朋友注意到这里的函数不是之前在DES中出现过的:ProcessBlock,
48
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//而是多了一个Xor。其实,ProcessAndXorBlock也有DES版本。用法跟AES版本差不多。
49
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//笔者分别在两份代码中列出这两个函数,有兴趣的朋友可以自己研究一下有何差异。
50
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
aesDecryptor.ProcessAndXorBlock( outBlock, xorBlock, plainText );
51
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
52
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
53
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
for( int i=0; i<16; i++ )
54
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
55
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << plainText[i];
56
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
57
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << endl;
58
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
59
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
60
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
61
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
62
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
其实来到这里,都可以发现,加密解密的套路也差不多,至于之后笔者在误打误撞中找到的RSA,也只不过是在设置密匙的时候多了私匙和公匙的区别而已。笔者总觉得,有完整的例程对照学习,是一件很幸福的事情。
非对称加密算法:
RSA:
小背景:
其实,笔者在一开始并没有接到“了解RSA”的要求。不过由于笔者很粗心,在看AES的时候只记得A和S两个字母,Google的时候就误打误撞Google了一个RSA。其实RSA方面的资料还是挺多的,因此它事实上是笔者第一个编译运行成功的Crypto++库中算法的应用实例。
http://www.cnblogs.com/cxun/archive/2008/07/30/743541.html
以下代码主要是按照上述URL中提供的代码写成的,作为笔者的第一份有效学习资料,笔者认为作为调用者的我们,不用清楚算法实现的细节。只需要明白几个主要函数的功用和调用的次序即可。
由以下代码可以看出,其实RSA也离不开:数据准备、设置密匙(注意,有公匙和私匙)、加密解密这样的套路。至于如何产生密匙,有兴趣的朋友可以到Crypto++的主页上下载源文件研究。作为入门和了解阶段,笔者觉得:只需要用起来即可。
1
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//version at Crypto++ 5.60
2
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "randpool.h"
3
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "rsa.h"
4
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "hex.h"
5
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "files.h"
6
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <iostream>
7
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
8
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
9
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace CryptoPP;
10
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
11
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#pragma comment(lib, "cryptlib.lib")
12
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
13
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
14
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
15
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
16
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 函数声明
17
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
18
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
19
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
20
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void GenerateRSAKey( unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed );
21
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
string RSAEncryptString( const char *pubFilename, const char *seed, const char *message );
22
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
string RSADecryptString( const char *privFilename, const char *ciphertext );
23
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
RandomPool & GlobalRNG();
24
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
25
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
26
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 主程序
27
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
28
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
29
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void main( void )
30
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
31
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
32
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
char priKey[ 128 ] =
![](http://www.cppblog.com/Images/dot.gif)
{ 0 };
33
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
char pubKey[ 128 ] =
![](http://www.cppblog.com/Images/dot.gif)
{ 0 };
34
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
char seed[ 1024 ] =
![](http://www.cppblog.com/Images/dot.gif)
{ 0 };
35
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
36
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// 生成 RSA 密钥对
37
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy( priKey, "pri" ); // 生成的私钥文件
38
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy( pubKey, "pub" ); // 生成的公钥文件
39
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy( seed, "seed" );
40
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
GenerateRSAKey( 1024, priKey, pubKey, seed );
41
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
42
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// RSA 加解密
43
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
char message[ 1024 ] =
![](http://www.cppblog.com/Images/dot.gif)
{ 0 };
44
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout<< "Origin Text:\t" << "Hello World!" << endl << endl;
45
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy( message, "Hello World!" );
46
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string encryptedText = RSAEncryptString( pubKey, seed, message ); // RSA 公匙加密
47
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout<<"Encrypted Text:\t"<< encryptedText << endl << endl;
48
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string decryptedText = RSADecryptString( priKey, encryptedText.c_str() ); // RSA 私匙解密
49
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
50
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
51
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
52
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
53
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
54
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
55
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 生成RSA密钥对
56
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
57
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
58
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
59
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
60
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
61
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RandomPool randPool;
62
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
randPool.Put((byte *)seed, strlen(seed));
63
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
64
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
65
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
HexEncoder privFile(new FileSink(privFilename));
66
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
67
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
priv.DEREncode(privFile);
68
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
privFile.MessageEnd();
69
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
70
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RSAES_OAEP_SHA_Encryptor pub(priv);
71
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
HexEncoder pubFile(new FileSink(pubFilename));
72
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
pub.DEREncode(pubFile);
73
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
74
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
pubFile.MessageEnd();
75
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
76
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ;
77
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
78
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
79
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
80
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
81
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
82
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
83
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// RSA加密
84
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
85
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
86
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
87
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
string RSAEncryptString( const char *pubFilename, const char *seed, const char *message )
88
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
89
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
FileSource pubFile( pubFilename, true, new HexDecoder );
90
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RSAES_OAEP_SHA_Encryptor pub( pubFile );
91
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
92
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RandomPool randPool;
93
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
randPool.Put( (byte *)seed, strlen(seed) );
94
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
95
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string result;
96
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
StringSource( message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))) );
97
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
98
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return result;
99
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
100
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
101
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
102
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
103
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
104
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// RSA解密
105
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
106
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
107
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
string RSADecryptString( const char *privFilename, const char *ciphertext )
108
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
109
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
FileSource privFile( privFilename, true, new HexDecoder );
110
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
RSAES_OAEP_SHA_Decryptor priv(privFile);
111
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
112
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string result;
113
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
StringSource( ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))) );
114
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
115
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return result;
116
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
117
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
118
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
119
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
120
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
121
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
122
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
// 定义全局的随机数池
123
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
124
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//------------------------
125
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
126
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
RandomPool & GlobalRNG()
127
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
128
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
static RandomPool randomPool;
129
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return randomPool;
130
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
131
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
132
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
散列算法:
SHA-256
SHA-256主要是用来求一大段信息的Hash值,跟之前三个用于加密、解密的算法有所不同。用到SHA的场合,多半是为了校验文件。
笔者的参考资料:http://hi.baidu.com/magic475/blog/item/19b37a8c1fa15a14b21bbaeb.html
请注意,笔者在实现的时候,稍微修改了一下两个子函数的实现,以满足笔者的需求。因此会与上述URL中的代码有差异。
1
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//http://hi.baidu.com/magic475/blog/item/19b37a8c1fa15a14b21bbaeb.html
2
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <iostream>
3
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include <string.h>
4
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
5
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "sha.h"
6
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "secblock.h"
7
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "modes.h"
8
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#include "hex.h"
9
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
10
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#pragma comment( lib, "cryptlib.lib")
11
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
12
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
13
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace CryptoPP;
14
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
15
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void CalculateDigest(string &Digest, const string &Message);
16
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
bool VerifyDigest(const string &Digest, const string &Message);
17
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
18
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int main( void )
19
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
20
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//main函数中注释掉的,关于strMessage2的代码,其实是笔者模拟了一下
21
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//通过求Hash值来对“大”量数据进行校验的这个功能的运用。
22
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//注释之后并不影响这段代码表达的思想和流程。
23
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string strMessage( "Hello world" );
24
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string strDigest;
25
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//string strMessage2( "hello world" ); //只是第一个字母不同
26
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//string strDigest2;
27
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
28
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
CalculateDigest( strDigest, strMessage ); //计算Hash值并打印一些debug信息
29
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "the size of Digest is: " << strDigest.size() << endl;
30
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "Digest is: " << strDigest << endl;
31
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
32
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//CalculateDigest( strDigest2, strMessage2 );
33
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//why put this function here will affect the Verify function?
34
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//作者在写代码的过程中遇到的上述问题。
35
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//如果把这行代码的注释取消,那么之后的运行结果就不是预料中的一样:
36
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//即使strDigest也无法对应strMessage,笔者不知道为什么,希望高手指出,谢谢!
37
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
38
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
bool bIsSuccess = false;
39
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
bIsSuccess = VerifyDigest( strDigest, strMessage );
40
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//通过校验,看看strDigest是否对应原来的message
41
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( bIsSuccess )
42
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
43
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "sussessive verify" << endl;
44
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "origin string is: " << strMessage << endl << endl;
45
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
46
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
else
47
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
48
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "fail!" << endl;
49
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
50
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
51
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//通过strDigest2与strMessage进行校验,要是相等,
52
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//就证明strDigest2是对应的strMessage2跟strMessage1相等。
53
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//否则,像这个程序中的例子一样,两个message是不相等的
54
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif)
/**//*CalculateDigest( strDigest2, strMessage2 );
55
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
bIsSuccess = VerifyDigest( strDigest2, strMessage );
56
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if( !bIsSuccess )
57
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
{
58
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "success! the tiny modification is discovered~" << endl;
59
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "the origin message is: \n" << strMessage << endl;
60
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "after modify is: \n" << strMessage2 << endl;
61
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}*/
62
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return 0;
63
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
64
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
65
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
66
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//基于某些原因,以下两个子函数的实现跟原来参考代码中的实现有所区别,
67
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
//详细原因,笔者在CalculateDigest函数的注释中写明
68
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void CalculateDigest(string &Digest, const string &Message)
69
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
70
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
SHA256 sha256;
71
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int DigestSize = sha256.DigestSize();
72
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
char* byDigest;
73
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
char* strDigest;
74
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
75
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
byDigest = new char[ DigestSize ];
76
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strDigest = new char[ DigestSize * 2 + 1 ];
77
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
78
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
sha256.CalculateDigest((byte*)byDigest, (const byte *)Message.c_str(), Message.size());
79
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
memset(strDigest, 0, sizeof(strDigest));
80
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//uCharToHex(strDigest, byDigest, DigestSize);
81
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//参考的代码中有以上这么一行,但是貌似不是什么库函数。
82
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//原作者大概是想把Hash值转换成16进制数保存到一个string buffer中,
83
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//然后在主程序中输出,方便debug的时候对照查看。
84
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//但是这并不影响计算Hash值的行为。
85
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//因此笔者注释掉了这行代码,并且修改了一下这个函数和后面的VerifyDigest函数,
86
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//略去原作者这部分的意图,继续我们的程序执行。
87
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
88
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
Digest = byDigest;
89
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
90
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
delete []byDigest;
91
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
byDigest = NULL;
92
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
delete []strDigest;
93
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strDigest = NULL;
94
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
95
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return;
96
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
97
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
98
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
bool VerifyDigest(const string &Digest, const string &Message)
99
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cppblog.com/Images/dot.gif)
{
100
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
bool Result;
101
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
SHA256 sha256;
102
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
char* byDigest;
103
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
104
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
byDigest = new char[ sha256.DigestSize() ];
105
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy( byDigest, Digest.c_str() );
106
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
107
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//HexTouChar(byDigest, Digest.c_str(), Digest.size());
108
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//为何注释掉,请参看CalculateDigest函数的注释
109
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
Result = sha256.VerifyDigest( (byte*)byDigest, (const byte *)Message.c_str(), Message.size() );
110
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
111
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
delete []byDigest;
112
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
byDigest = NULL;
113
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return Result;
114
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
115
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
116
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
后记:
为什么写这篇文章呢?因为笔者在搜索过程中觉得这方面的资料有点分散,因此想把它们集中起来,方便刚刚入门的朋友。
同时,也算是为自己留点学习资料吧。
相关文章推荐
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
- AES DES RSA SHA MD5优缺点
- 加密算法概念简介--MD5、SHA、DES、3DES、AES、RSA、ECC
- 常用加解密工具类(MD5、SHA、DES、AES、RSA)
- 【JAVA】常用加解密算法总结及JAVA实现【BASE64,MD5,SHA,DES,3DES,AES,RSA】
- 常用加解密工具类(MD5、SHA、DES、AES、RSA)
- 常用加解密工具类(MD5、SHA、DES、AES、RSA)