快速业务通道

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

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30

运行环境: 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. 加入库连接: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);
   }
 
  }
} // 结束

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号