How to: Get plain text session key with an encrypted API
Operating environment: VC6 SP5, 2000 SP1, NT4 SP3
It is important to obtain a session secret key in the usual programming. However, Microsoft's encryption operation API (whether the foundation or enhanced) can provide this feature. CryptExportKey () and cryptimportKey () each require an effective key handle to encrypt and decrypt the session key. MSDN demonstrates a method of using a private key. However, Microsoft's example is quite long in MSDN. The following methods are not only faster and more effective.
Before running this example, you need to set the following parameters in Project -> Settings (Visual Studio 6.0):
1. Add a C preprocessing definition:
_WIN32_WINNT = 0x0500, _crypt32_ (win2k)
Or _win32_winnt = 0x0400, _crypt32_ (NT4)
2. Join the library connection:
{0> Crypt32.lib <} 0 {>? Crypt32.lib
The example code is as follows:? <0}
#include
#include
#include
#define key_pair_size dwsize - 12
#define session_key_size dwKeyMaRial
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;
}
/ / -------------------------------------------------------------------------------------------- ---
// Create a session key. In this example we will use a 168-bit 3DES key.
IF (! CryptGenkey (HPROV, CALG_3DES,
Crypt_exportable, & hsessionKey))))
{
__leave;
}
/ / -------------------------------------------------------------------------------------------- ---
// Get the handle of the switching key pair
IF (! CryptgetUserKey (HPROV, AT_KEYEXCHANGE, & HEXCHANGEKEYPAIR)
{
__leave;
}
/ / -------------------------------------------------------------------------------------------- ------------
// Encrypt the session key with the key pair
// First first get the necessary byte size of the encrypted session key
/ / Then output it.
IF (! CryptexportKey (HSessionKey,
HEXChangeKeypair,
Simpleblob,
0,
NULL,
& dwsize))
{
__leave;
}
PBEXPORTEDKEYBLOB = New Byte [dwsize];
IF (! CryptexportKey (HSessionKey,
HEXChangeKeypair,
Simpleblob,
0,
PBEXPORTEDKEYBLOB,
& dwsize))
{
__leave;
}
/ / -------------------------------------------------------------------------------------------- ------------
// We delete the first 12-byte size BLOB information
PbencryptedKey = new byte [key_pair_size];
For (c = 0; c { PbencryptedKey [c] = pbexportedKeyblob [C 12]; } / / -------------------------------------------------------------------------------------------- ------------ / / At this time we use the private key part of the key pair to get the value of the session key. IF (! CryptDecrypt (HexchangeKeyPair, 0, True, 0, PbencryptedKey, & dwKeyMaTerial)) { __leave; } / / -------------------------------------------------------------------------------------------- ------- // PBKEYMATERIAL stores the value of the key PBKEYMATERIAL = New byte [session_key_size]; For (c = 0; c { PBKEYMATERIAL [C] = PbencryptedKey [C]; } } __finally { IF (PBKEYMATERIAL) LOCALFREE (PBKEYMATERIAL); IF (HSessionKey) CryptDestroyKey (HSessionKey); IF (HexchangeKeyPair) CryptDestroyKey (HexchangeKeyPair); IF (HPROV) { CryptreleaseContext (hprov, 0); } } } // End