转自http://www.cppblog.com/ArthasLee/archive/2010/12/01/135186.html

 

最近,基于某些原因和需要,笔者需要去了解一下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的论坛回帖,但是作了些修改:

 

 1Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include <iostream>
 2Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include <des.h>
 3Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 4Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#pragma comment( lib, "cryptlib.lib" )
 5Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 6Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)using namespace std;
 7Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)using namespace CryptoPP;
 8Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 9Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)int main( void )
10

 

 回想一下以上代码的编写过程,就可以发现,进行DES加密,流程大概是:
       数据准备;
       构造加密器;
       设置加密密匙;
       加密数据;
       显示(非必要);
       设置解密密匙(跟加密密匙是同一个key);
       解密数据;
       验证与显示(非必要);
       由此可见,主要函数的调用流程就是这样。但是文档没有详细讲,笔者当时打开下载回来的源文件时,就傻了眼。
猜想:
       AES和以后的算法,是不是都是按照这些基本的套路呢?


       AES:    

       在实际运用的时候,从代码上看,AES跟DES非常相像。但是值得注意一点的是,AES取代了DES成为21世纪的加密标准。是因为以其密匙长度和高安全性获得了先天优势。虽然界面上看上去没多大区别,但是破解难度远远大于DES。详细情况,在之前的URL有提及过。
     
       很幸运,笔者很快就找到了AES的使用例程,而且很详细:
      http://dev.firnow.com/course/3_program/c++/cppsl/2008827/138033.html

 1Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include <iostream>
 2Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include <aes.h>
 3Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 4Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#pragma comment( lib, "cryptlib.lib" )
 5Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 6Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)using namespace std; 
 7Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)using namespace CryptoPP;
 8Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 9Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)int main()
10


其实来到这里,都可以发现,加密解密的套路也差不多,至于之后笔者在误打误撞中找到的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++的主页上下载源文件研究。作为入门和了解阶段,笔者觉得:只需要用起来即可。

  1Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)//version at Crypto++ 5.60
  2Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include "randpool.h"
  3Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include "rsa.h"
  4Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include "hex.h"
  5Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include "files.h"
  6Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include <iostream>
  7Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
  8Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)using namespace std;
  9Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)using namespace CryptoPP;
 10Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 11Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#pragma comment(lib, "cryptlib.lib")
 12Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 13Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 14Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)//------------------------
 15Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 16Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)// 函数声明
 17Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 18Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)//------------------------
 19Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 20Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)void GenerateRSAKey( unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed  );
 21Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)string RSAEncryptString( const char *pubFilename, const char *seed, const char *message );
 22Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)string RSADecryptString( const char *privFilename, const char *ciphertext );
 23Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)RandomPool & GlobalRNG();
 24Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 25Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)//------------------------
 26Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)// 主程序
 27Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)//------------------------
 28Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 29Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)void main( void )
 30Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 31


 

散列算法:


SHA-256                                                                                                                                                                                                                                                                      

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

  1Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)//http://hi.baidu.com/magic475/blog/item/19b37a8c1fa15a14b21bbaeb.html
  2Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include <iostream>
  3Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include <string.h>
  4Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
  5Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include "sha.h"
  6Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include "secblock.h"
  7Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include "modes.h"
  8Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#include "hex.h"
  9Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 10Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)#pragma comment( lib, "cryptlib.lib")
 11Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 12Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)using namespace std;
 13Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)using namespace CryptoPP;
 14Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 15Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)void CalculateDigest(string &Digest, const string &Message);
 16Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)bool VerifyDigest(const string &Digest, const string &Message);
 17Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
 18Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)int main( void )
 19

 



        后记:
        为什么写这篇文章呢?因为笔者在搜索过程中觉得这方面的资料有点分散,因此想把它们集中起来,方便刚刚入门的朋友。
         同时,也算是为自己留点学习资料吧。


鸣谢:
jingzhongrong
vczh 
没了这两位,在这个宇宙、这个时间、这个维度肯定不会有这篇文章,哈哈!

相关文章: