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接口方法
...
namespaceCryptoPP32
{
boolCRYPTOPP32_DLLRSAES_OAEP_GenerateKeys(constchar*privFilename,constchar*pubFilename,unsignedintkeyLength=512,constchar*seed=0);
boolCRYPTOPP32_DLLRSAES_OAEP_GenerateKeys(string&strPrivKey,string&strPubKey,unsignedintkeyLength=512,constchar*seed=0);

boolCRYPTOPP32_DLLRSAES_OAEP_EncryptString(constchar*pubFilename,constchar*message,string&cipher,constchar*seed=0);
boolCRYPTOPP32_DLLRSAES_OAEP_DecryptString(constchar*privFilename,constchar*cipher,string&message);

boolCRYPTOPP32_DLLRSAES_OAEP_EncryptString(conststring&strPubKey,constchar*message,string&cipher,constchar*seed=0);
boolCRYPTOPP32_DLLRSAES_OAEP_DecryptString(conststring&strPrivKey,constchar*cipher,string&plain);

boolCRYPTOPP32_DLLRSAES_OAEP_EncryptString(constchar*N,constchar*E,constchar*message,string&cipher,constchar*seed=0);
boolCRYPTOPP32_DLLRSAES_OAEP_DecryptString(constchar*N,constchar*E,constchar*D,constchar*P,constchar*Q,constchar*dP,constchar*dQ,constchar*U,constchar*cipher,string&plain);

boolCRYPTOPP32_DLLRSAES_PKCS_GenerateKeys(constchar*privFilename,constchar*pubFilename,unsignedintkeyLength=512,constchar*seed=0);
boolCRYPTOPP32_DLLRSAES_PKCS_GenerateKeys(string&strPrivKey,string&strPubKey,unsignedintkeyLength=512,constchar*seed=0);

boolCRYPTOPP32_DLLRSAES_PKCS_EncryptString(constchar*pubFilename,constchar*message,string&cipher,constchar*seed=0);
boolCRYPTOPP32_DLLRSAES_PKCS_EncryptString(conststring&strPubKey,constchar*message,string&cipher,constchar*seed=0);

boolCRYPTOPP32_DLLRSAES_PKCS_DecryptString(constchar*privFilename,constchar*cipher,string&message);
boolCRYPTOPP32_DLLRSAES_PKCS_DecryptString(conststring&strPrivKey,constchar*cipher,string&plain);

boolCRYPTOPP32_DLLRSAES_PKCS_EncryptString(constchar*N,constchar*E,constchar*message,string&cipher,constchar*seed=0);
boolCRYPTOPP32_DLLRSAES_PKCS_DecryptString(constchar*N,constchar*E,constchar*D,constchar*P,constchar*Q,constchar*dP,constchar*dQ,constchar*U,constchar*cipher,string&plain);

boolCRYPTOPP32_DLLRSASS_PKCS_Sign(constchar*privFilename,constchar*msgFilename,constchar*signFilename,constchar*hashFunc="SHA");
boolCRYPTOPP32_DLLRSASS_PKCS_Verify(constchar*pubFilename,constchar*msgFilename,constchar*signFilename,constchar*hashFunc="SHA");

boolCRYPTOPP32_DLLRSASS_PKCS_Sign(conststring&strPrivKey,constchar*message,string&signature,constchar*hashFunc="SHA");
boolCRYPTOPP32_DLLRSASS_PKCS_Verify(conststring&strPubKey,constchar*message,conststring&signature,constchar*hashFunc="SHA");

boolCRYPTOPP32_DLLHMAC_SHA1_EncryptString(constchar*inString,constchar*passPhrase,string&outString);
boolCRYPTOPP32_DLLHMAC_SHA1_DecryptString(constchar*inString,constchar*passPhrase,string&outString);

boolCRYPTOPP32_DLLHMAC_SHA1_EncryptFile(constchar*inFilename,constchar*outFilename,constchar*passPhrase);
boolCRYPTOPP32_DLLHMAC_SHA1_DecryptFile(constchar*inFilename,constchar*outFilename,constchar*passPhrase);

boolCRYPTOPP32_DLLGzipFile(constchar*inFilename,constchar*outFilename,intdeflateLevel);
boolCRYPTOPP32_DLLGunzipFile(constchar*inFilename,constchar*outFilename);

boolCRYPTOPP32_DLLBase64Encode(constchar*inFilename,constchar*outFilename);
boolCRYPTOPP32_DLLBase64Decode(constchar*inFilename,constchar*outFilename);

boolCRYPTOPP32_DLLBase64Encode(constchar*plain,string&encoded);
boolCRYPTOPP32_DLLBase64Decode(constchar*encoded,string&plain);

boolCRYPTOPP32_DLLHexEncode(constchar*inFilename,constchar*outFilename);
boolCRYPTOPP32_DLLHexDecode(constchar*inFilename,constchar*outFilename);

boolCRYPTOPP32_DLLHexEncode(constchar*plain,string&encoded);
boolCRYPTOPP32_DLLHexDecode(constchar*encoded,string&plain);
};
读者可以通过我提供的代码来弄懂CryptoPP54的使用方法,也可以通过下面的例子,来使用我包装的CryptoPP32.dll:
//testCryptoPP32.cpp:定义控制台应用程序的入口点。
//作者:张亮
//cheungmine@gmail.com

#include
"stdafx.h"

#defineCRYPTOPP32_IMPORTS

#include
"../CryptoPP32_DLL/CryptoPP32.h"

//动态连接CryptoPP32.DLL
#ifdef_DEBUG
#pragmacomment(lib,"../CryptoPP32_DLL/Debug/CryptoPP32d.lib")
#else
#pragmacomment(lib,"../CryptoPP32_DLL/Release/CryptoPP32.lib")
#endif

usingnamespaceCryptoPP32;


int_tmain(intargc,_TCHAR*argv[])
{
//生成公钥和私钥文件
CryptoPP32::RSAES_PKCS_GenerateKeys("c:/privkey.rsa","c:/pubkey.rsa");

//生成公钥和私钥字符串
stringstrPriv;
stringstrPub;
CryptoPP32::RSAES_PKCS_GenerateKeys(strPriv,strPub);

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

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

//使用公钥串加密字符串:"thisisatest!上海"
stringcipher2;
CryptoPP32::RSAES_PKCS_EncryptString(strPub,
"thisisatest!上海",cipher2);

//使用私钥串解密字符串
stringplain2;
boolbres2=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
charn[]="C4E3F7212602E1E396C0B6623CF11D26204ACE3E7D26685E037AD2507DCE82FC28F2D5F8A67FC3AFAB89A6D818D1F4C28CFA548418BD9F8E7426789A67E73E41h";
chare[]="10001h";
chard[]="7cd1745aec69096129b1f42da52ac9eae0afebbe0bc2ec89253598dcf454960e3e5e4ec9f8c87202b986601dd167253ee3fb3fa047e14f1dfd5ccd37e931b29dh";
charp[]="f0e4dd1eac5622bd3932860fc749bbc48662edabdf3d2826059acc0251ac0d3bh";
charq[]="d13cb38fbcd06ee9bca330b4000b3dae5dae12b27e5173e4d888c325cda61ab3h";
chardp[]="b3d5571197fc31b0eb6b4153b425e24c033b054d22b9c8282254fe69d8c8c593h";
chardq[]="968ffe89e50d7b72585a79b65cfdb9c1da0963cceb56c3759e57334de5a0ac3fh";
charu[]="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);


return0;
}
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信息传输过程的安全问题(仍没解决服务和客户欺诈的问题,这不是本文讨论的议题)。
最后,我很希望看到读者的评论,因为我这方面的知识实在太欠缺了!
阅读更多
换一批

没有更多推荐了,返回首页