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

 

如何:        用加密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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值