0
点赞
收藏
分享

微信扫一扫

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静态编译进去了。


我在下面的地址:


http://www.3snews.net/index.php/5890/action_viewspace_itemid_9580.html


提供了整个工程的文件下载,包括 cryptopp5.4、CryptoPP32和测试项目。用户必须使用VC7.1打开CryptoPP32_DLL目录下的sln文件。第一次编译,必须在生成管理器中选中cryptlib。


   

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 : 定义控制台应用程序的入口点。

   //
    作者:张亮

   //

   

    
#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类似,可以从下面的网址得到它的源代码:


http://www-cs-students.stanford.edu/~tjw/jsbn/

 


当你了解了JSBN使用的参数:n, e, d, p, q, dp, dq, u的意义和加密解密的技巧,回过来使用 CryptoPP32 ,就知道我所说的含义了。经过测试,CryptoPP32可以正确解密JSBN的加密的东西,反之亦然。在CryptoPP32中,仅用到了下面2个函数:


RSAES_PKCS_EncryptString


RSAES_PKCS_DecryptString


 


3 应用情景


         在一般目的使用的情形下:服务和客户每个会话都重新生成的私钥和密钥,然后交换公钥;客户使用服务的公钥加密信息,然后传给服务,服务使用自己的私钥解密;同样,服务使用客户的公钥加密信息,客户使用私钥解密这一信息。这样,在目前的 B/S环境下,不用给客户添加任何负担,即解决了internet信息传输过程的安全问题(仍没解决服务和客户欺诈的问题,这不是本文讨论的议题)。


   


最后,我很希望看到读者的评论,因为我这方面的知识实在太欠缺了!

举报

相关推荐

0 条评论