最先附上 下载地址

背景(只是个人感想,技术上不对后面的内容构成知识性障碍,可以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. #include <iostream>
  2. #include <des.h>
  3.  
  4. #pragma comment( lib, "cryptlib.lib" )
  5. using namespace std;
  6. 7using namespace CryptoPP;
  7. int main( void )
  8. {
  9. //主要是打印一些基本信息,方便调试:
  10. cout << "DES Parameters: " << endl;
  11. cout << "Algorithm name : " << DES::StaticAlgorithmName() << endl;
  12.  
  13. unsigned char key[ DES::DEFAULT_KEYLENGTH ];
  14. unsigned char input[ DES::BLOCKSIZE ] = "";
  15. unsigned char output[ DES::BLOCKSIZE ];
  16. unsigned char txt[ DES::BLOCKSIZE ];
  17.  
  18. cout << "input is: " << input << endl;
  19.  
  20. //可以理解成首先构造一个加密器
  21. DESEncryption encryption_DES;
  22.  
  23. //回忆一下之前的背景,对称加密算法需要一个密匙。加密和解密都会用到。
  24. //因此,设置密匙。
  25. encryption_DES.SetKey( key, DES::KEYLENGTH );
  26. //进行加密
  27. encryption_DES.ProcessBlock( input, output );
  28.  
  29. //显示结果
  30. //for和for之后的cout可有可无,主要为了运行的时候看加密结果
  31. //把字符串的长度写成一个常量其实并不被推荐。
  32. //不过笔者事先知道字符串长,为了方便调试,就直接写下。
  33. //这里主要是把output也就是加密后的内容,以十六进制的整数形式输出。
  34. for( int i = ; i < ; i++ )
  35. {
  36. cout << hex << (int)output[ i ] << ends;
  37. }
  38. cout << endl;
  39.  
  40. //构造一个加密器
  41. DESDecryption decryption_DES;
  42.  
  43. //由于对称加密算法的加密和解密都是同一个密匙,
  44. //因此解密的时候设置的密匙也是刚才在加密时设置好的key
  45. decryption_DES.SetKey( key, DES::KEYLENGTH );
  46. //进行解密,把结果写到txt中
  47. //decryption_DES.ProcessAndXorBlock( output, xorBlock, txt );
  48. decryption_DES.ProcessBlock( output, txt );
  49.  
  50. //以上,加密,解密还原过程已经结束了。以下是为了验证:
  51. //加密前的明文和解密后的译文是否相等。
  52. if ( memcmp( input, txt, ) != )
  53. {
  54. cerr << "DES Encryption/decryption failed.\n";
  55. abort();
  56. }
  57. cout << "DES Encryption/decryption succeeded.\n";
  58.  
  59. return ;
  60. }

回想一下以上代码的编写过程,就可以发现,进行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. #include <iostream>
  2. #include <aes.h>
  3.  
  4. #pragma comment( lib, "cryptlib.lib" )
  5. using namespace std;
  6. using namespace CryptoPP;
  7. int main()
  8. {
  9. //AES中使用的固定参数是以类AES中定义的enum数据类型出现的,而不是成员函数或变量
  10. //因此需要用::符号来索引
  11. cout << "AES Parameters: " << endl;
  12. cout << "Algorithm name : " << AES::StaticAlgorithmName() << endl;
  13.  
  14. //Crypto++库中一般用字节数来表示长度,而不是常用的字节数
  15. cout << "Block size : " << AES::BLOCKSIZE * << endl;
  16. cout << "Min key length : " << AES::MIN_KEYLENGTH * << endl;
  17. cout << "Max key length : " << AES::MAX_KEYLENGTH * << endl;
  18.  
  19. //AES中只包含一些固定的数据,而加密解密的功能由AESEncryption和AESDecryption来完成
  20. //加密过程
  21. AESEncryption aesEncryptor; //加密器
  22.  
  23. unsigned char aesKey[AES::DEFAULT_KEYLENGTH]; //密钥
  24. unsigned char inBlock[AES::BLOCKSIZE] = ""; //要加密的数据块
  25. unsigned char outBlock[AES::BLOCKSIZE]; //加密后的密文块
  26. unsigned char xorBlock[AES::BLOCKSIZE]; //必须设定为全零
  27.  
  28. memset( xorBlock, , AES::BLOCKSIZE ); //置零
  29.  
  30. aesEncryptor.SetKey( aesKey, AES::DEFAULT_KEYLENGTH ); //设定加密密钥
  31. aesEncryptor.ProcessAndXorBlock( inBlock, xorBlock, outBlock ); //加密
  32.  
  33. //以16进制显示加密后的数据
  34. for( int i=; i<; i++ ) {
  35. cout << hex << (int)outBlock[i] << " ";
  36. }
  37. cout << endl;
  38.  
  39. //解密
  40. AESDecryption aesDecryptor;
  41. unsigned char plainText[AES::BLOCKSIZE];
  42.  
  43. aesDecryptor.SetKey( aesKey, AES::DEFAULT_KEYLENGTH );
  44. //细心的朋友注意到这里的函数不是之前在DES中出现过的:ProcessBlock,
  45. //而是多了一个Xor。其实,ProcessAndXorBlock也有DES版本。用法跟AES版本差不多。
  46. //笔者分别在两份代码中列出这两个函数,有兴趣的朋友可以自己研究一下有何差异。
  47. aesDecryptor.ProcessAndXorBlock( outBlock, xorBlock, plainText );
  48.  
  49. for( int i=; i<; i++ )
  50. {
  51. cout << plainText[i];
  52. }
  53. cout << endl;
  54.  
  55. return ;
  56.  
  57. }

其实来到这里,都可以发现,加密解密的套路也差不多,至于之后笔者在误打误撞中找到的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. //version at Crypto++ 5.60
  2. #include "randpool.h"
  3. #include "rsa.h"
  4. #include "hex.h"
  5. #include "files.h"
  6. #include <iostream>
  7. using namespace std;
  8. 9using namespace CryptoPP;
  9.  
  10. #pragma comment(lib, "cryptlib.lib")
  11.  
  12. //------------------------
  13.  
  14. // 函数声明
  15.  
  16. //------------------------
  17. void GenerateRSAKey( unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed );
  18. 21string RSAEncryptString( const char *pubFilename, const char *seed, const char *message );
  19. 22string RSADecryptString( const char *privFilename, const char *ciphertext );
  20. 23RandomPool & GlobalRNG();
  21.  
  22. //------------------------
  23. // 主程序
  24. //------------------------
  25. void main( void )
  26.  
  27. {
  28. char priKey[ ] = { };
  29. char pubKey[ ] = { };
  30. char seed[ ] = { };
  31.  
  32. // 生成 RSA 密钥对
  33. strcpy( priKey, "pri" ); // 生成的私钥文件
  34. strcpy( pubKey, "pub" ); // 生成的公钥文件
  35. strcpy( seed, "seed" );
  36. GenerateRSAKey( , priKey, pubKey, seed );
  37.  
  38. // RSA 加解密
  39. char message[ ] = { };
  40. cout<< "Origin Text:\t" << "Hello World!" << endl << endl;
  41. strcpy( message, "Hello World!" );
  42. string encryptedText = RSAEncryptString( pubKey, seed, message ); // RSA 公匙加密
  43. cout<<"Encrypted Text:\t"<< encryptedText << endl << endl;
  44. string decryptedText = RSADecryptString( priKey, encryptedText.c_str() ); // RSA 私匙解密
  45. }
  46.  
  47. //------------------------
  48.  
  49. // 生成RSA密钥对
  50.  
  51. //------------------------
  52. void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
  53. {
  54. RandomPool randPool;
  55. randPool.Put((byte *)seed, strlen(seed));
  56.  
  57. RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
  58. HexEncoder privFile(new FileSink(privFilename));
  59.  
  60. priv.DEREncode(privFile);
  61. privFile.MessageEnd();
  62.  
  63. RSAES_OAEP_SHA_Encryptor pub(priv);
  64. HexEncoder pubFile(new FileSink(pubFilename));
  65. pub.DEREncode(pubFile);
  66.  
  67. pubFile.MessageEnd();
  68.  
  69. return
  70. }
  71.  
  72. //------------------------
  73.  
  74. // RSA加密
  75.  
  76. //------------------------
  77. string RSAEncryptString( const char *pubFilename, const char *seed, const char *message )
  78. {
  79. FileSource pubFile( pubFilename, true, new HexDecoder );
  80. RSAES_OAEP_SHA_Encryptor pub( pubFile );
  81.  
  82. RandomPool randPool;
  83. randPool.Put( (byte *)seed, strlen(seed) );
  84.  
  85. string result;
  86. StringSource( message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))) );
  87.  
  88. return result;
  89. }
  90.  
  91. //------------------------
  92. // RSA解密
  93. //------------------------
  94. string RSADecryptString( const char *privFilename, const char *ciphertext )
  95. {
  96. FileSource privFile( privFilename, true, new HexDecoder );
  97. RSAES_OAEP_SHA_Decryptor priv(privFile);
  98.  
  99. string result;
  100. StringSource( ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))) );
  101.  
  102. return result;
  103. }
  104.  
  105. //------------------------
  106.  
  107. // 定义全局的随机数池
  108.  
  109. //------------------------
  110.  
  111. 126RandomPool & GlobalRNG()
  112. {
  113. static RandomPool randomPool;
  114. return randomPool;
  115. }

散列算法:

SHA-256

SHA-256主要是用来求一大段信息的Hash值,跟之前三个用于加密、解密的算法有所不同。用到SHA的场合,多半是为了校验文件。
       
         笔者的参考资料:http://hi.baidu.com/magic475/blog/item/19b37a8c1fa15a14b21bbaeb.html
       请注意,笔者在实现的时候,稍微修改了一下两个子函数的实现,以满足笔者的需求。因此会与上述URL中的代码有差异。

  1. //http://hi.baidu.com/magic475/blog/item/19b37a8c1fa15a14b21bbaeb.html
  2. #include <iostream>
  3. #include <string.h>
  4.  
  5. #include "sha.h"
  6. #include "secblock.h"
  7. #include "modes.h"
  8. #include "hex.h"
  9.  
  10. #pragma comment( lib, "cryptlib.lib")
  11. using namespace std;
  12. 13using namespace CryptoPP;
  13. void CalculateDigest(string &Digest, const string &Message);
  14. 16bool VerifyDigest(const string &Digest, const string &Message);
  15. int main( void )
  16. {
  17. //main函数中注释掉的,关于strMessage2的代码,其实是笔者模拟了一下
  18. //通过求Hash值来对“大”量数据进行校验的这个功能的运用。
  19. //注释之后并不影响这段代码表达的思想和流程。
  20. string strMessage( "Hello world" );
  21. string strDigest;
  22. //string strMessage2( "hello world" ); //只是第一个字母不同
  23. //string strDigest2;
  24.  
  25. CalculateDigest( strDigest, strMessage ); //计算Hash值并打印一些debug信息
  26. cout << "the size of Digest is: " << strDigest.size() << endl;
  27. cout << "Digest is: " << strDigest << endl;
  28.  
  29. //CalculateDigest( strDigest2, strMessage2 );
  30. //why put this function here will affect the Verify function?
  31. //作者在写代码的过程中遇到的上述问题。
  32. //如果把这行代码的注释取消,那么之后的运行结果就不是预料中的一样:
  33. //即使strDigest也无法对应strMessage,笔者不知道为什么,希望高手指出,谢谢!
  34.  
  35. bool bIsSuccess = false;
  36. bIsSuccess = VerifyDigest( strDigest, strMessage );
  37. //通过校验,看看strDigest是否对应原来的message
  38. if( bIsSuccess )
  39. {
  40. cout << "sussessive verify" << endl;
  41. cout << "origin string is: " << strMessage << endl << endl;
  42. }
  43. else
  44. {
  45. cout << "fail!" << endl;
  46. }
  47.  
  48. //通过strDigest2与strMessage进行校验,要是相等,
  49. //就证明strDigest2是对应的strMessage2跟strMessage1相等。
  50. //否则,像这个程序中的例子一样,两个message是不相等的
  51. /*CalculateDigest( strDigest2, strMessage2 );
  52. 55 bIsSuccess = VerifyDigest( strDigest2, strMessage );
  53. 56 if( !bIsSuccess )
  54. 57 {
  55. 58 cout << "success! the tiny modification is discovered~" << endl;
  56. 59 cout << "the origin message is: \n" << strMessage << endl;
  57. 60 cout << "after modify is: \n" << strMessage2 << endl;
  58. 61 }*/
  59. return ;
  60. }
  61.  
  62. //基于某些原因,以下两个子函数的实现跟原来参考代码中的实现有所区别,
  63. //详细原因,笔者在CalculateDigest函数的注释中写明
  64. 68void CalculateDigest(string &Digest, const string &Message)
  65. {
  66. SHA256 sha256;
  67. int DigestSize = sha256.DigestSize();
  68. char* byDigest;
  69. char* strDigest;
  70.  
  71. byDigest = new char[ DigestSize ];
  72. strDigest = new char[ DigestSize * + ];
  73.  
  74. sha256.CalculateDigest((byte*)byDigest, (const byte *)Message.c_str(), Message.size());
  75. memset(strDigest, , sizeof(strDigest));
  76. //uCharToHex(strDigest, byDigest, DigestSize);
  77. //参考的代码中有以上这么一行,但是貌似不是什么库函数。
  78. //原作者大概是想把Hash值转换成16进制数保存到一个string buffer中,
  79. //然后在主程序中输出,方便debug的时候对照查看。
  80. //但是这并不影响计算Hash值的行为。
  81. //因此笔者注释掉了这行代码,并且修改了一下这个函数和后面的VerifyDigest函数,
  82. //略去原作者这部分的意图,继续我们的程序执行。
  83.  
  84. Digest = byDigest;
  85.  
  86. delete []byDigest;
  87. byDigest = NULL;
  88. delete []strDigest;
  89. strDigest = NULL;
  90.  
  91. return;
  92. }
  93. bool VerifyDigest(const string &Digest, const string &Message)
  94. {
  95. bool Result;
  96. SHA256 sha256;
  97. char* byDigest;
  98.  
  99. byDigest = new char[ sha256.DigestSize() ];
  100. strcpy( byDigest, Digest.c_str() );
  101.  
  102. //HexTouChar(byDigest, Digest.c_str(), Digest.size());
  103. //为何注释掉,请参看CalculateDigest函数的注释
  104. Result = sha256.VerifyDigest( (byte*)byDigest, (const byte *)Message.c_str(), Message.size() );
  105.  
  106. delete []byDigest;
  107. byDigest = NULL;
  108. return Result;
  109. }
如果下载了库不知道怎么编译的:可以看看
 

crypto++的安装
首先到www.cryptopp.com上下载最新版本的源代码,如果是windows版的,会得到一个vc的项目,直接用vc打开就可以编译了。这里建议大家使用最新版的c++编译器,因为诸如vc6的编译器是不支持c++的标准的,很多符合c++标准的代码不能编译通过。编译的时间比较长,完成后会生成cryptlib.lib这个库文件。可以将crypto++源文件的目录命名为cryptopp,拷贝到编译器的include目录(例如:c:\vs.net\vc7\include),将cryptlib.lib文件拷贝到编译器的lib目录。这样我们只需要说明链接cryptlib.lib即可。例如在vc7中在项目->属性->链接器->命令行->附加选项中添加“cryptlib.lib”。

hello world
现在写一个hello world程序看看能不能编译通过。

#include <iostream>
using namespace std;

#include <cryptopp/aes.h>
using namespace cryptopp;

int main()
{
       cout << "hello crypto++" << endl;
       cout << "aes block size is " << aes::blocksize << endl;

return 0;
}

编译运行,一切ok,哈哈:d,可以用了。

 
 
 
前面AES的demo好像不能用  再发一个
 
 
 
 

Crypto++是个免费的C++加解密类库,由于资格太老、持续更新,最新版本到了CryptoPP 5.6,对天缘而言,第一眼看到CryptoPP就感觉头大,根目录下放置大量单源文件、编译文件、项目文件,再加上多平台和多编译器支持,文件几乎又多了一倍,而且还是都混到一起,直接就让人望而却步。毕竟Crypto是个功能完整,且经过大量用户使用考验的开源库。所以,皱眉学习汇总一下,遂成此文。

官方网址:http://www.cryptopp.com/

本文测试环境:Windows7 SP1+VC6,测试工程名为Test。用VC打开CryptoPP工程文件,会发现有四个子工程:

  • cryptdll - 生成cryptopp.dll动态库
  • dlltest - 用来测试cryptopp.dll,依赖cryptdll工程
  • cryptlib - 生成cryptlib.lib静态库
  • cryptest - 用来测试cryptopp,依赖cryptlib工程

所以,我们有两种使用CryptoPP方法,一种是静态链接,还有一种是动态链接,使用对应的工程编译即可,区别就不说了,我们下文以静态链接为例,介绍几种常用加解密算法使用。

一、编译cryptlib

首先需要编译cryptlib,最后得到cryptlib.lib文件。

  1. 先在测试工程Test下创建目录cryptopp\lib和cryptopp\include,并把Project Settings-C/C++-Processor下Include目录增加“cryptopp\include”。
  2. 把cryptlib.lib拷贝到Test\cryptopp\lib下。
  3. 把cryptoPP根目录下所有的*.h文件都拷贝到Test\cryptopp\include下。当然实际上用不了那么多,后续用到哪个include哪个。

下文开始测试使用CryptoPP,实际使用中,如果功能上逻辑上需要修改,可以参考上文测试工程中的示例程序,以及官方文档。下文编译如果报告XX重复定义等错误,请检查LIB库工程和本测试工程的:Project Setting-C/C++-Code Generation User run-time library是否统一。

二、测试cryptlib

1、测试MD5

  1. #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
  2. #include "md5.h"
  3. using namespace CryptoPP;
  4. #pragma comment(lib, "cryptopp\\lib\\cryptlib.lib")
  5.  
  6. using namespace std;
  7.  
  8. void main() {
  9.  
  10. byte message[]="HelloWorld!";
  11. byte mres[16];//MD5 128 bits=16bytes
  12.  
  13. Weak::MD5 md5;
  14. md5.Update(message,11);//strlen=11
  15. md5.Final(mres);
  16.  
  17. for(int i=0;i<16;i++)
  18. printf("%02X",mres[i]);
  19.  
  20. printf("\n");
  21. }

2、测试AES

  1. //For AES encrypt
  2. #include "default.h"
  3. #include "cryptlib.h"
  4. #include "filters.h"
  5. #include "bench.h"
  6. #include "osrng.h"
  7. #include "hex.h"
  8. #include "modes.h"
  9. #include "files.h"
  10.  
  11. using namespace CryptoPP;
  12. #pragma comment(lib, "cryptopp\\lib\\cryptlib.lib")
  13.  
  14. using namespace std;
  15.  
  16. void main() {
  17.  
  18. unsigned char key[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x01,0x02, 0x03,0x04,0x05,0x06,0x07,0x08};//AES::DEFAULT_KEYLENGTH
  19. unsigned char iv[] = {0x01,0x02,0x03,0x03,0x03,0x03,0x03,0x03, 0x03,0x03, 0x01,0x02,0x03,0x03,0x03,0x03};
  20. int keysize = 16;
  21.  
  22. string message = "Hello World!";
  23. string strEncTxt;
  24. string strDecTxt;
  25.  
  26. //CBC - PADDING
  27. //AES-CBC Encrypt(ONE_AND_ZEROS_PADDING)
  28. CBC_Mode<AES>::Encryption Encryptor1(key,keysize,iv);
  29. StringSource( message,
  30. true,
  31. new StreamTransformationFilter( Encryptor1,
  32. new StringSink( strEncTxt ),
  33. BlockPaddingSchemeDef::BlockPaddingScheme::ONE_AND_ZEROS_PADDING,
  34. true)
  35. );
  36.  
  37. //AES-CBC Decrypt
  38. CBC_Mode<AES>::Decryption Decryptor1(key,keysize,iv);
  39. StringSource( strEncTxt,
  40. true,
  41. new StreamTransformationFilter( Decryptor1,
  42. new StringSink( strDecTxt ),
  43. BlockPaddingSchemeDef::BlockPaddingScheme::ONE_AND_ZEROS_PADDING,
  44. true)
  45. );
  46.  
  47. //CTR - NO_PADDING
  48. //AES-CTR Encrypt
  49. CTR_Mode<AES>::Encryption Encryptor2(key,keysize,iv);
  50. StringSource( message,
  51. true,
  52. new StreamTransformationFilter( Encryptor2,
  53. new StringSink( strEncTxt ),
  54. BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING,
  55. true)
  56. );
  57.  
  58. //AES-CTR Decrypt
  59. CTR_Mode<AES>::Decryption Decryptor2(key,keysize,iv);
  60. StringSource( strEncTxt,
  61. true,
  62. new StreamTransformationFilter( Decryptor2,
  63. new StringSink( strDecTxt ),
  64. BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING,
  65. true)
  66. );
  67.  
  68. }

上文是使用StringSource方式加密字符串,还可以使用FileSource方式直接对文件进行加解密操作。示例如下:

  1. SecByteBlock HexDecodeString(const char *hex) {
  2. StringSource ss(hex, true, new HexDecoder);
  3. SecByteBlock result((size_t)ss.MaxRetrievable());
  4. ss.Get(result, result.size());
  5. return result;
  6. }
  7.  
  8. void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile) {
  9. SecByteBlock key = HexDecodeString(hexKey);
  10. SecByteBlock iv = HexDecodeString(hexIV);
  11.  
  12. CTR_Mode<AES>::Encryption aes(key, key.size(), iv);
  13.  
  14. FileSource(infile, true, new StreamTransformationFilter(aes, new FileSink(outfile)));
  15. }

直接调用AES_CTR_Encrypt函数即可,CBC函数需对应修改。

四、使用提示

1、StringSource类定义filters.h

  1. //! zero terminated string as source
  2. StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
  3. : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
  4. //! binary byte array as source
  5. StringSource(const byte *string, size_t length, bool pumpAll, BufferedTransformation *attachment = NULL)
  6. : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
  7. //! std::string as source
  8. StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
  9. : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}

2、RSA有关的加解密、签名函数

更多请参考工程cryptest工程下test.cpp文件内函数

  1. void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);
  2. string RSAEncryptString(const char *pubFilename, const char *seed, const char *message);
  3. string RSADecryptString(const char *privFilename, const char *ciphertext);
  4. void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename);
  5. bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename);

Crypto++入门学习笔记(DES、AES、RSA、SHA-256)的更多相关文章

  1. Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)

    转自http://www.cppblog.com/ArthasLee/archive/2010/12/01/135186.html 最近,基于某些原因和需要,笔者需要去了解一下Crypto++库,然后 ...

  2. Hadoop入门学习笔记---part1

    随着毕业设计的进行,大学四年正式进入尾声.任你玩四年的大学的最后一次作业最后在激烈的选题中尘埃落定.无论选择了怎样的选题,无论最后的结果是怎样的,对于大学里面的这最后一份作业,也希望自己能够尽心尽力, ...

  3. Hadoop入门学习笔记---part4

    紧接着<Hadoop入门学习笔记---part3>中的继续了解如何用java在程序中操作HDFS. 众所周知,对文件的操作无非是创建,查看,下载,删除.下面我们就开始应用java程序进行操 ...

  4. Hadoop入门学习笔记---part3

    2015年元旦,好好学习,天天向上.良好的开端是成功的一半,任何学习都不能中断,只有坚持才会出结果.继续学习Hadoop.冰冻三尺,非一日之寒! 经过Hadoop的伪分布集群环境的搭建,基本对Hado ...

  5. PyQt4入门学习笔记(三)

    # PyQt4入门学习笔记(三) PyQt4内的布局 布局方式是我们控制我们的GUI页面内各个控件的排放位置的.我们可以通过两种基本方式来控制: 1.绝对位置 2.layout类 绝对位置 这种方式要 ...

  6. PyQt4入门学习笔记(一)

    PyQt4入门学习笔记(一) 一直没有找到什么好的pyqt4的教程,偶然在google上搜到一篇不错的入门文档,翻译过来,留以后再复习. 原始链接如下: http://zetcode.com/gui/ ...

  7. Hadoop入门学习笔记---part2

    在<Hadoop入门学习笔记---part1>中感觉自己虽然总结的比较详细,但是始终感觉有点凌乱.不够系统化,不够简洁.经过自己的推敲和总结,现在在此处概括性的总结一下,认为在准备搭建ha ...

  8. Scala入门学习笔记三--数组使用

    前言 本篇主要讲Scala的Array.BufferArray.List,更多教程请参考:Scala教程 本篇知识点概括 若长度固定则使用Array,若长度可能有 变化则使用ArrayBuffer 提 ...

  9. OpenCV入门学习笔记

    OpenCV入门学习笔记 参照OpenCV中文论坛相关文档(http://www.opencv.org.cn/) 一.简介 OpenCV(Open Source Computer Vision),开源 ...

随机推荐

  1. python 进程锁 生产者消费者模型 队列 (进程其他方法,守护进程,数据共享,进程隔离验证)

    #######################总结######### 主要理解 锁      生产者消费者模型 解耦用的   队列 共享资源的时候 是不安全的 所以用到后面的锁 守护进程:p.daem ...

  2. Hadoop记录-yarn ResourceManager Active频繁易主问题排查(转载)

    一.故障现象 两个节点的ResourceManger频繁在active和standby角色中切换.不断有active易主的告警发出 许多任务的状态没能成功更新,导致一些任务状态卡在NEW_SAVING ...

  3. Entity Framework 学习总结之十一:POCO

    POCO Entity Framework 4.0 为实体提供了简单传统 CLR 对象( Plain Old CLR Object / POCO )支持.实体对象可以独立于 EF 存在,由此 EF 更 ...

  4. 未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持。如果希望使用通知,请为此数据库启用 Service Broker

    昨晚遇到的这个问题,也知道Notifications service依赖底层的Service broker的.本以为只需要执行以下脚本对数据库启用Service broker即可. alter dat ...

  5. 错误 1 “Entities.PlanPrjEntity.PlanPrjs”不可访问,因为它受保护级别限制

    本人第一次是用List做父类,写了一个类PlanPrjs,如下: class PlanPrj { public int ID { get; set; } public string Name { ge ...

  6. 【python小练】0010

    第 0010 题:使用 Python 生成类似于下图中的字母验证码图片 思路: 1. 随机生成字符串 2. 创建画布往上头写字符串 3. 干扰画面 code: # codeing: utf-8 fro ...

  7. 本地测试使用Tomcat,生产环境使用GlassFish。

    总结:Tomcat8 = javaee7规范(servlet3.1 + jsp2.3 + el3.0 + websocket1.0) + java7 [配置初始化参数使用jdk8编译]conf/web ...

  8. Docker(四)Dockerfile入门

    摘自: https://mp.weixin.qq.com/s/Im4axroExgrJoj05g_TQ-w 一.Docker的工作流程 Docker组件协作运行容器可以分为以下几个过程: Docker ...

  9. Chrome之控制台使用【转载】

    原文链接:https://segmentfault.com/a/1190000002511877 关键API: console.log(); console.info(); console.warn( ...

  10. 第25月第5天 Hands-on Machine Learning with Scikit-Learn and TensorFlow

    1.apachecn视频(机器学习实战) https://github.com/apachecn/AiLearning https://space.bilibili.com/97678687/#/ch ...