程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 如何用加密API獲得純文本的會話密鑰

如何用加密API獲得純文本的會話密鑰

編輯:關於C++

運行環境: 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);
   }
 
  }
} // 結束

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved