CryptoPP 使用方法

Posted 车斗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CryptoPP 使用方法相关的知识,希望对你有一定的参考价值。

Crypto++ 使用方法
 
——长时间以来,没增加新文章!凡所增加,必属原创。
2007-7-24
 
0 引言
为阅读本文,读者需要具备密码学最基本的知识,如:对称加密和非对称加密、数字签名等。还好,准备这些知识,一个下午的时间就足够了。
许多朋友问我如何使用 CryptoPP(目前最新版本为5.4),我以前也没用过,但一直觉得是个好东西,属于经典的C++库之一。因此,有必要把它作为我的软件基石之一。我以前是用Windows的Crypt API的,ATL有对应的封装类。但是,我遇到了一个问题之后,决定放弃Crypt API。原因是,我使用Win2003加密的东西,在Win2000上解密失败。很火大。水平有限,时间有限,就不深入寻找原因了。
改投开源的 CryptoPP C++库门下,发现CryptoPP的用法诡异,到处是陷阱一样的模板,对于我这个对密码学本身略知皮毛的人来说,无疑是雪上加霜。头一次使用,以失败而铩羽。但是,CryptoPP在业界的好名声,使我不忍放弃,时隔半年之后,我终于重读CryptoPP的例子,摸索出使用方法。但是,直接使用CryptoPP真的很烦琐,索性包装为DLL,我把它取名字叫:CryptoPP32.dll。直接使用CryptoPP32.dll,不需要任何cryptopp5.4的库,因为我已经把cryptopp5.4静态编译进去了。
我在下面的地址:
提供了整个工程的文件下载,包括 cryptopp5.4、CryptoPP32和测试项目。用户必须使用VC7.1打开CryptoPP32_DLL目录下的sln文件。第一次编译,必须在生成管理器中选中cryptlib。
 
(我不知道 CSDN如何上传文件。本人提供的下载文件,可以任意散发,复制,但不得改变作者声明。CSDN有很多地方做的不够友好,希望改进!希望CSDN的BLOG编写组学学http://www.3snews.net的BLOG,比你们的强很多啊!)
 
1 CryptoPP54与CryptoPP32
下面是 CryptoPP32.h接口文件的方法:
 
// CryptoPP32.DLL接口方法
...
namespace  CryptoPP32
{       
bool  CRYPTOPP32_DLL RSAES_OAEP_GenerateKeys( const   char   * privFilename,  const   char   * pubFilename, unsigned  int  keyLength = 512 const   char   * seed = 0 );
bool  CRYPTOPP32_DLL RSAES_OAEP_GenerateKeys( string &  strPrivKey,  string &  strPubKey, unsigned  int  keyLength = 512 const   char   * seed = 0 );
 
bool  CRYPTOPP32_DLL RSAES_OAEP_EncryptString( const   char   * pubFilename,  const   char   * message,  string &  cipher,  const   char   * seed = 0 );
bool  CRYPTOPP32_DLL RSAES_OAEP_DecryptString( const   char   * privFilename,  const   char   * cipher,  string &  message);
 
bool  CRYPTOPP32_DLL RSAES_OAEP_EncryptString( const   string &  strPubKey,  const   char   * message,  string &  cipher,  const   char   * seed = 0 );
bool  CRYPTOPP32_DLL RSAES_OAEP_DecryptString( const   string &  strPrivKey,  const   char   * cipher,  string &  plain);
 
bool  CRYPTOPP32_DLL RSAES_OAEP_EncryptString( const   char *  N,  const   char *  E,  const   char *  message,  string &  cipher,  const   char *  seed = 0 );
bool  CRYPTOPP32_DLL RSAES_OAEP_DecryptString( const   char *  N,  const   char *  E,  const   char *  D,  const   char *  P,  const   char *  Q,  const   char *  dP,  const   char *  dQ,  const   char *  U,  const   char *  cipher,  string &  plain);
 
bool  CRYPTOPP32_DLL RSAES_PKCS_GenerateKeys( const   char   * privFilename,  const   char   * pubFilename, unsigned  int  keyLength = 512 const   char   * seed = 0 );
bool  CRYPTOPP32_DLL RSAES_PKCS_GenerateKeys( string &  strPrivKey,  string &  strPubKey, unsigned  int  keyLength = 512 const   char   * seed = 0 );
 
bool  CRYPTOPP32_DLL RSAES_PKCS_EncryptString( const   char   * pubFilename,  const   char   * message,  string &  cipher,  const   char   * seed = 0 );
bool  CRYPTOPP32_DLL RSAES_PKCS_EncryptString( const   string &  strPubKey,  const   char   * message,  string &  cipher,  const   char   * seed = 0 );
 
bool  CRYPTOPP32_DLL RSAES_PKCS_DecryptString( const   char   * privFilename,  const   char   * cipher,  string &  message);
bool  CRYPTOPP32_DLL RSAES_PKCS_DecryptString( const   string &  strPrivKey,  const   char   * cipher,  string &  plain);
 
bool  CRYPTOPP32_DLL RSAES_PKCS_EncryptString( const   char *  N,  const   char *  E,  const   char *  message,  string &  cipher,  const   char *  seed = 0 );
bool  CRYPTOPP32_DLL RSAES_PKCS_DecryptString( const   char *  N,  const   char *  E,  const   char *  D,  const   char *  P,  const   char *  Q,  const   char *  dP,  const   char *  dQ,  const   char *  U,  const   char *  cipher,  string &  plain);
 
bool  CRYPTOPP32_DLL RSASS_PKCS_Sign( const   char   * privFilename,  const   char   * msgFilename,  const   char   * signFilename,  const   char   * hashFunc = " SHA " );
bool  CRYPTOPP32_DLL RSASS_PKCS_Verify( const   char   * pubFilename,  const   char   * msgFilename,  const   char   * signFilename,  const   char   * hashFunc = " SHA " );
 
bool  CRYPTOPP32_DLL RSASS_PKCS_Sign( const   string &  strPrivKey,  const   char   * message,  string &  signature,  const   char   * hashFunc = " SHA " );
bool  CRYPTOPP32_DLL RSASS_PKCS_Verify( const   string &  strPubKey,  const   char   * message,  const   string &  signature,  const   char   * hashFunc = " SHA " );
 
bool  CRYPTOPP32_DLL HMAC_SHA1_EncryptString( const   char   * inString,  const   char   * passPhrase,  string &  outString);
bool  CRYPTOPP32_DLL HMAC_SHA1_DecryptString( const   char   * inString,  const   char   * passPhrase,  string &  outString);
 
bool  CRYPTOPP32_DLL HMAC_SHA1_EncryptFile( const   char   * inFilename,  const   char   * outFilename,  const   char   * passPhrase);
bool  CRYPTOPP32_DLL HMAC_SHA1_DecryptFile( const   char   * inFilename,  const   char   * outFilename,  const   char   * passPhrase);
 
bool  CRYPTOPP32_DLL GzipFile( const   char   * inFilename,  const   char   * outFilename,  int  deflateLevel);
bool  CRYPTOPP32_DLL GunzipFile( const   char   * inFilename,  const   char   * outFilename);
 
bool  CRYPTOPP32_DLL Base64Encode( const   char   * inFilename,  const   char   * outFilename);
bool  CRYPTOPP32_DLL Base64Decode( const   char   * inFilename,  const   char   * outFilename);
 
bool  CRYPTOPP32_DLL Base64Encode( const   char   * plain,  string &  encoded);
bool  CRYPTOPP32_DLL Base64Decode( const   char   * encoded,  string &  plain);
 
bool  CRYPTOPP32_DLL HexEncode( const   char   * inFilename,  const   char   * outFilename);
bool  CRYPTOPP32_DLL HexDecode( const   char   * inFilename,  const   char   * outFilename);
 
bool  CRYPTOPP32_DLL HexEncode( const   char   * plain,  string &  encoded);
bool  CRYPTOPP32_DLL HexDecode( const   char   * encoded,  string &  plain);
};
 
 
读者可以通过我提供的代码来弄懂 CryptoPP54的使用方法,也可以通过下面的例子,来使用我包装的CryptoPP32.dll:
 
//  testCryptoPP32.cpp : 定义控制台应用程序的入口点。
//  作者:张亮
//  cheungmine@gmail.com
 
#include 
" stdafx.h "
 
#define  CRYPTOPP32_IMPORTS
 
#include 
" ../CryptoPP32_DLL/CryptoPP32.h "
 
//  动态连接 CryptoPP32.DLL
#ifdef _DEBUG
#pragma  comment(lib, "../CryptoPP32_DLL/Debug/CryptoPP32d.lib")
#else
#pragma  comment(lib, "../CryptoPP32_DLL/Release/CryptoPP32.lib")
#endif
 
using   namespace  CryptoPP32;
 
 
int  _tmain( int  argc, _TCHAR *  argv[])
{
    
//  生成公钥和私钥文件
    CryptoPP32::RSAES_PKCS_GenerateKeys( " c:/privkey.rsa " " c:/pubkey.rsa " ); 
 
    
//  生成公钥和私钥字符串
     string  strPriv;
    
string  strPub;
    CryptoPP32::RSAES_PKCS_GenerateKeys(strPriv, strPub);
 
    
//  使用公钥文件加密字符串:hello world
     string  cipher;
    CryptoPP32::RSAES_PKCS_EncryptString(
" c:/pubkey.rsa " " hello world " , cipher,  " 242352ef45tcrewrdwe5ctfdd " ); 
    
    
//  使用私钥文件解密字符串
     string  plain;
    
bool  bres  =  CryptoPP32::RSAES_PKCS_DecryptString( " c:/privkey.rsa " , cipher.c_str(), plain); 
 
    
//  使用公钥串加密字符串:"this is a test! 上海"
     string  cipher2;
    CryptoPP32::RSAES_PKCS_EncryptString(strPub, 
" this is a test! 上海 " , cipher2); 
 
    
//  使用私钥串解密字符串
     string  plain2;
    
bool  bres2  =  CryptoPP32::RSAES_PKCS_DecryptString(strPriv, cipher2.c_str(), plain2); 
 
    
//  
    
//  下面的用法与下面地址介绍内容的一致:
    
//        http://www-cs-students.stanford.edu/ ~tjw/jsbn/
    
//  JSBN使用的参数:n, e, d, p, q, dp, dq, u
     char  n[] = " C4E3F7212602E1E396C0B6623CF11D26204ACE3E7D26685E037AD2507DCE82FC28F2D5F8A67FC3AFAB89A6D818D1F4C28CFA548418BD9F8E7426789A67E73E41h " ;
    
char  e[] = " 10001h " ;
    
char  d[] = " 7cd1745aec69096129b1f42da52ac9eae0afebbe0bc2ec89253598dcf454960e3e5e4ec9f8c87202b986601dd167253ee3fb3fa047e14f1dfd5ccd37e931b29dh " ;
    
char  p[] = " f0e4dd1eac5622bd3932860fc749bbc48662edabdf3d2826059acc0251ac0d3bh " ;
    
char  q[] = " d13cb38fbcd06ee9bca330b4000b3dae5dae12b27e5173e4d888c325cda61ab3h " ;
    
char  dp[] = " b3d5571197fc31b0eb6b4153b425e24c033b054d22b9c8282254fe69d8c8c593h " ;
    
char  dq[] = " 968ffe89e50d7b72585a79b65cfdb9c1da0963cceb56c3759e57334de5a0ac3fh " ;
    
char  u[] = " d9bc4f420e93adad9f007d0e5744c2fe051c9ed9d3c9b65f439a18e13d6e3908h " ;
 
    bres
=  CryptoPP32::RSAES_PKCS_EncryptString(n, e,  " test " , cipher); 
 
    bres
=  CryptoPP32::RSAES_PKCS_DecryptString(n, e, d, p, q, dp, dq, u, cipher.c_str(), plain);
 
 
    
return   0 ;
}
 
 
2 CryptoPP32与JavaScript
        我再次强调我的偏好: javascript——真正的浏览器语言。我包装CryptoPP54的目的就是要使它和JavaScript(JS)对应的类库jsbn用法一致。这样,使用浏览器的客户端可以用JSBN,服务端使用CryptoPP32。
Browser(JSBN) <---------> Server(CryptoPP32) 

         JSBN是一套开源的JavaScript加密库。目的与CryptoPP类似,可以从下面的网址得到它的源代码:

 
当你了解了JSBN使用的参数:n, e, d, p, q, dp, dq, u的意义和加密解密的技巧,回过来使用 CryptoPP32 ,就知道我所说的含义了。经过测试,CryptoPP32可以正确解密JSBN的加密的东西,反之亦然。在CryptoPP32中,仅用到了下面2个函数:
RSAES_PKCS_EncryptString
RSAES_PKCS_DecryptString
 
3 应用情景
         在一般目的使用的情形下:服务和客户每个会话都重新生成的私钥和密钥,然后交换公钥;客户使用服务的公钥加密信息,然后传给服务,服务使用自己的私钥解密;同样,服务使用客户的公钥加密信息,客户使用私钥解密这一信息。这样,在目前的 B/S环境下,不用给客户添加任何负担,即解决了internet信息传输过程的安全问题(仍没解决服务和客户欺诈的问题,这不是本文讨论的议题)。
   
最后,我很希望看到读者的评论,因为我这方面的知识实在太欠缺了!
 

以上是关于CryptoPP 使用方法的主要内容,如果未能解决你的问题,请参考以下文章

CryptoPP 使用方法

如何使用 mingw 编译 cryptopp 5.6.2

如何在使用 CryptoPP 解密流后执行 unpadding

由cryptopp创建的DER编码公钥与openssl不同

编译时错误:未定义对 CryptoPP::StringStore::TransferTo2 的引用

cryptopp 加密库的安装