Introduction
Generally it's very important to obtain the value of session keys. However, the
Microsoft Cryptographic Providers (Base and Enhanced) does not support this
feature. CryptExportKey() and CryptImportKey() require
a valid key handle to encrypt and decrypt the session key, respectively. MSDN
shows a way to do this using a exponent-of-one private key. This article shows a
better way to perform the same process. This way is faster and more
comprehensive.
It's ready to run, but you must set the following parameters at Project ->
Settings (Visual Studio 6.0 ) :
- Add in C++/Preprocessor definitions: _WIN32_WINNT=0x0500, _CRYPT32_(WIN2K)
or _WIN32_WINNT=0x0400, _CRYPT32_(NT4)
- And Link this library
crypt32.lib
Code Listing
#include <windows.h>
#include <wincrypt.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;
}
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;
}
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 = 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);
}
}
}
Raphael Amorim
Software Developer (Senior)
Instituto Atlântico
Brazil
Member
Follow on Twitter
|
Senior Software Developer Engineer @ Instituto Atlântico
Summary:
• Has Acted as Software Architect and Technical Leader in many projects
• Good knowledge of Windows Internals
• More than 9 years of software design and development experience in Visual C/C++.
• More than 8 years of experience in Security/Cryptography software design and programming.
• Good knowledge of .NET framework and C# language, also using ASP.NET.
• Good knowledge of Lua Scripting Language
• Good knowledge of Objective C and Cocoa.
• Good knowledge of Java language.
• Good knowledge of MacOSX/Linux programming in C++
• Good knowledge of Brew Framework for CDMA cell phone software development (using C)
• Some knowledge of Carbon and Qt application development C++.
Specialist in:
Visual C++® and C, MFC, ATL, COM, STL, ActiveX, Lua, Cocoa, Carbon and Qt application development, C# and Java (J2SE and J2ME), Brew Framework for CDMA, Linux Programming in C++, PocketPC (embedded C++ and .NET Compact Framework) , Device Driver Development , SQL Server 6.5/7/2000/2005, MySQL, IBM DB2 and Access Visual C++ 6.0, Visual Studio .NET (all versions), Eclipse, NetBeans, XCode, Qt Creator and Carbide. Microsoft Windows NT to 7, Windows CE 3.0/5.0/6.0, Mac OS X and Linux.
|