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

    技术2022-05-11  91

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


    运行环境: VC6 SP5, 2000 SP1,NT4 SP3

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

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

    1.添加C++预处理定义:

       _WIN32_WINNT=0x0500, _CRYPT32_(WIN2K)

     或者 _WIN32_WINNT=0x0400, _CRYPT32_(NT4)

    2. 加入库连接

    {0>  crypt32.lib <}0{>?  crypt32.lib

     

    例子代码如下:?<0}

    #include <windows.h> #include <wincrypt.h> #include <stdio.h>   #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)