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);
};
...
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 ;
}
// 作者:张亮
// 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 解密流后执行 unpadding