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_DLLRSAES_OAEP_GenerateKeys( const char * privFilename, const char * pubFilename,unsigned int keyLength = 512 , const char * seed = 0 );
bool CRYPTOPP32_DLLRSAES_OAEP_GenerateKeys( string & strPrivKey, string & strPubKey,unsigned int keyLength = 512 , const char * seed = 0 );

bool CRYPTOPP32_DLLRSAES_OAEP_EncryptString( const char * pubFilename, const char * message, string & cipher, const char * seed = 0 );
bool CRYPTOPP32_DLLRSAES_OAEP_DecryptString( const char * privFilename, const char * cipher, string & message);

bool CRYPTOPP32_DLLRSAES_OAEP_EncryptString( const string & strPubKey, const char * message, string & cipher, const char * seed = 0 );
bool CRYPTOPP32_DLLRSAES_OAEP_DecryptString( const string & strPrivKey, const char * cipher, string & plain);

bool CRYPTOPP32_DLLRSAES_OAEP_EncryptString( const char * N, const char * E, const char * message, string & cipher, const char * seed = 0 );
bool CRYPTOPP32_DLLRSAES_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_DLLRSAES_PKCS_GenerateKeys( const char * privFilename, const char * pubFilename,unsigned int keyLength = 512 , const char * seed = 0 );
bool CRYPTOPP32_DLLRSAES_PKCS_GenerateKeys( string & strPrivKey, string & strPubKey,unsigned int keyLength = 512 , const char * seed = 0 );

bool CRYPTOPP32_DLLRSAES_PKCS_EncryptString( const char * pubFilename, const char * message, string & cipher, const char * seed = 0 );
bool CRYPTOPP32_DLLRSAES_PKCS_EncryptString( const string & strPubKey, const char * message, string & cipher, const char * seed = 0 );

bool CRYPTOPP32_DLLRSAES_PKCS_DecryptString( const char * privFilename, const char * cipher, string & message);
bool CRYPTOPP32_DLLRSAES_PKCS_DecryptString( const string & strPrivKey, const char * cipher, string & plain);

bool CRYPTOPP32_DLLRSAES_PKCS_EncryptString( const char * N, const char * E, const char * message, string & cipher, const char * seed = 0 );
bool CRYPTOPP32_DLLRSAES_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_DLLRSASS_PKCS_Sign( const char * privFilename, const char * msgFilename, const char * signFilename, const char * hashFunc = " SHA " );
bool CRYPTOPP32_DLLRSASS_PKCS_Verify( const char * pubFilename, const char * msgFilename, const char * signFilename, const char * hashFunc = " SHA " );

bool CRYPTOPP32_DLLRSASS_PKCS_Sign( const string & strPrivKey, const char * message, string & signature, const char * hashFunc = " SHA " );
bool CRYPTOPP32_DLLRSASS_PKCS_Verify( const string & strPubKey, const char * message, const string & signature, const char * hashFunc = " SHA " );

bool CRYPTOPP32_DLLHMAC_SHA1_EncryptString( const char * inString, const char * passPhrase, string & outString);
bool CRYPTOPP32_DLLHMAC_SHA1_DecryptString( const char * inString, const char * passPhrase, string & outString);

bool CRYPTOPP32_DLLHMAC_SHA1_EncryptFile( const char * inFilename, const char * outFilename, const char * passPhrase);
bool CRYPTOPP32_DLLHMAC_SHA1_DecryptFile( const char * inFilename, const char * outFilename, const char * passPhrase);

bool CRYPTOPP32_DLLGzipFile( const char * inFilename, const char * outFilename, int deflateLevel);
bool CRYPTOPP32_DLLGunzipFile( const char * inFilename, const char * outFilename);

bool CRYPTOPP32_DLLBase64Encode( const char * inFilename, const char * outFilename);
bool CRYPTOPP32_DLLBase64Decode( const char * inFilename, const char * outFilename);

bool CRYPTOPP32_DLLBase64Encode( const char * plain, string & encoded);
bool CRYPTOPP32_DLLBase64Decode( const char * encoded, string & plain);

bool CRYPTOPP32_DLLHexEncode( const char * inFilename, const char * outFilename);
bool CRYPTOPP32_DLLHexDecode( const char * inFilename, const char * outFilename);

bool CRYPTOPP32_DLLHexEncode( const char * plain, string & encoded);
bool CRYPTOPP32_DLLHexDecode( 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);

// 使用公钥文件加密字符串:helloworld
string cipher;
CryptoPP32::RSAES_PKCS_EncryptString(
" c:/pubkey.rsa " , " helloworld " ,cipher, " 242352ef45tcrewrdwe5ctfdd " );

// 使用私钥文件解密字符串
string plain;
bool bres = CryptoPP32::RSAES_PKCS_DecryptString( " c:/privkey.rsa " ,cipher.c_str(),plain);

// 使用公钥串加密字符串:"thisisatest!上海"
string cipher2;
CryptoPP32::RSAES_PKCS_EncryptString(strPub,
" thisisatest!上海 " ,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信息传输过程的安全问题(仍没解决服务和客户欺诈的问题,这不是本文讨论的议题)。
最后,我很希望看到读者的评论,因为我这方面的知识实在太欠缺了!
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值