技术开发 频道

如何用加密API获得纯文本的会话密钥


【IT168技术文档】

  在通常的编程中获得会话密钥匙非常重要的。 然而,微软的加密操作API(无论是基础的还是增强的)都不能提供这项功能。 CryptExportKey() 和 CryptImportKey() 各自要求一个有效的密钥句柄来对会话密钥进行加密和解密。 MSDN 展示了一种使用私钥的方法。 但是微软的这个在MSDN中例子相当的长。 下面的这个方法不仅更快而且更有效。

  在运行这个例子前,需要在Project -> Settings (Visual Studio 6.0 ) 中对以下参数进行设置:

  1.添加C++预处理定义:_WIN32_WINNT=0x0500, _CRYPT32_(WIN2K)或者 _WIN32_WINNT=0x0400, _CRYPT32_(NT4)

  2. 加入库连接:crypt32.lib

  例子代码如下:
#include #include #include #define KEY_PAIR_SIZE   dwSize - 12 #define SESSION_KEY_SIZE dwKeyMaterial void main() {     HCRYPTPROV hProv = 0;   HCRYPTKEY hExchangeKeyPair = 0;   HCRYPTKEY hSessionKey = 0;   BYTE *pbKeyMaterial = NULL;   DWORD dwKeyMaterial ;    BYTE *pbExportedKeyBlob = NULL;   BYTE *pbEncryptedKey  = NULL;   DWORD dwSize;   unsigned int c;       __try   {       if (!CryptAcquireContext( &hProv,                "Container Name",                MS_ENHANCED_PROV ,                PROV_RSA_FULL,                CRYPT_MACHINE_KEYSET ))   {    __leave;   }     //---------------------------------------------------   //创建一个会话密钥。 在这个例子中我们将使用一个168位的3DES key。   if (!CryptGenKey( hProv, CALG_3DES,            CRYPT_EXPORTABLE, &hSessionKey ))   {    __leave;   }   //---------------------------------------------------   //得到交换密钥对的句柄            if (!CryptGetUserKey( hProv, AT_KEYEXCHANGE, &hExchangeKeyPair))   {    __leave;   }   //--------------------------------------------------------   //用密钥对中公钥部分对会话密钥进行加密   //第一次先获得已加密的会话密钥的必要字节大小   //然后将其输出。        if (!CryptExportKey( hSessionKey,              hExchangeKeyPair,              SIMPLEBLOB,              0,              NULL,              &dwSize))   {    __leave;   }   pbExportedKeyBlob = new BYTE[dwSize];   if (!CryptExportKey( hSessionKey,              hExchangeKeyPair,              SIMPLEBLOB,              0,              pbExportedKeyBlob,               &dwSize))   {    __leave;   }     //--------------------------------------------------------   //我们删除第一个12字节大小的Blob 信息        pbEncryptedKey = new BYTE [KEY_PAIR_SIZE];         for ( c = 0 ; c < KEY_PAIR_SIZE ; c++ )   {    pbEncryptedKey[c] = pbExportedKeyBlob[c+12];   }        //--------------------------------------------------------   //此时我们用密钥对中的私钥部分就可以得到会话密钥的值。        if (!CryptDecrypt( hExchangeKeyPair, 0,             TRUE, 0,              pbEncryptedKey, &dwKeyMaterial))   {    __leave;   }        //-------------------------------------------------------   // pbKeyMaterial中存放着密钥的值        pbKeyMaterial = new BYTE[ SESSION_KEY_SIZE ];        for  ( c = 0; c < SESSION_KEY_SIZE ; c++ )   {    pbKeyMaterial[c] = pbEncryptedKey[c];   }     }   __finally   {    if (pbKeyMaterial ) LocalFree(pbKeyMaterial );    if (hSessionKey) CryptDestroyKey(hSessionKey);    if (hExchangeKeyPair) CryptDestroyKey(hExchangeKeyPair);    if (hProv)    {       CryptReleaseContext(hProv, 0);    }     } } // 结束
0
相关文章