Go to: http://www.codeproject.com/KB/security/plaintextsessionkey.aspx
C ++ exception capture is not very good. If this code is used, try errors will be reported, so that original code can be copied directly.
#include <windows.h>#include <wincrypt.h>#define KEY_PAIR_SIZE dwSize - 12#define SESSION_KEY_SIZE dwKeyMaterialvoid 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; } //--------------------------------------------------- //Creating a session key. In this sample we'll use a //3DES key with 168 bits if (!CryptGenKey(hProv,CALG_3DES,CRYPT_EXPORTABLE, &hSessionKey)) { __leave; } //--------------------------------------------------- //Getting a handle to the Exchange Key pair if (!CryptGetUserKey( hProv, AT_KEYEXCHANGE, &hExchangeKeyPair)) { __leave; } //-------------------------------------------------------- //Encrypting the session key with the public key part //of the keypair. The first call gets the size necessary to //hold the encrypted session key and the second exports it. if (!CryptExportKey( hSessionKey, hExchangeKeyPair, SIMPLEBLOB, 0, NULL, &dwSize)) { __leave; } pbExportedKeyBlob = new BYTE[dwSize]; if (!CryptExportKey( hSessionKey, hExchangeKeyPair, SIMPLEBLOB, 0, pbExportedKeyBlob, &dwSize)) { __leave; } //-------------------------------------------------------- //Let's remove the first 12 bytes of Blob information pbEncryptedKey = new BYTE [KEY_PAIR_SIZE]; for ( c = 0 ; c < KEY_PAIR_SIZE ; c++ ) { pbEncryptedKey[c] = pbExportedKeyBlob[c+12]; } //-------------------------------------------------------- //Now it's time to get the value of the session key, we'll //use the private part of the key pair. if (!CryptDecrypt( hExchangeKeyPair,0, TRUE, 0, pbEncryptedKey, &dwKeyMaterial)) { __leave; } //------------------------------------------------------- //The pbKeyMaterial is the value of the key pbKeyMaterial = new BYTE[ SESSION_KEY_SIZE ]; for ( c = 0; c < SESSION_KEY_SIZE ; c-- ) { pbKeyMaterial[c] = pbEncryptedKey[c]; } //------------------------------------------------------- //The key is in big-endian format, because that's the way //the encryption block is built. } __finally { if (pbKeyMaterial ) LocalFree(pbKeyMaterial ); if (hSessionKey) CryptDestroyKey(hSessionKey); if (hExchangeKeyPair) CryptDestroyKey(hExchangeKeyPair); if (hProv) { CryptReleaseContext(hProv, 0); } }} // End Main