📄 handlecontainer.cpp
字号:
{
*hProv = 0;
*hPrivateKey = 0;
if ((dwKeySpec != AT_KEYEXCHANGE) && (dwKeySpec != AT_SIGNATURE)) __leave;
// Try to create new container
fResult = CryptAcquireContext(hProv, szContainer, szProvider,
dwProvType, CRYPT_NEWKEYSET);
if (!fResult)
{
// If the container exists, open it
if (GetLastError() == NTE_EXISTS)
{
fResult = CryptAcquireContext(hProv, szContainer, szProvider, dwProvType, 0);
if (!fResult)
{
TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
// No good, leave
__leave;
}
}
else
{
TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
// No good, leave
__leave;
}
}
// Generate the private key
fResult = CryptGenKey(*hProv, dwKeySpec, CRYPT_EXPORTABLE, hPrivateKey);
if (!fResult){
TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
__leave;
}
// Export the private key, we'll convert it to a private
// exponent of one key
fResult = CryptExportKey(*hPrivateKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwkeyblob);
if (!fResult){
TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
__leave;
}
keyblob = (LPBYTE)LocalAlloc(LPTR, dwkeyblob);
if (!keyblob){
TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
__leave;
}
fResult = CryptExportKey(*hPrivateKey, 0, PRIVATEKEYBLOB, 0, keyblob, &dwkeyblob);
if (!fResult){
TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
__leave;
}
CryptDestroyKey(*hPrivateKey);
*hPrivateKey = 0;
// Get the bit length of the key
memcpy(&dwBitLen, &keyblob[12], 4);
// Modify the Exponent in Key BLOB format
// Key BLOB format is documented in SDK
// Convert pubexp in rsapubkey to 1
ptr = &keyblob[16];
for (n = 0; n < 4; n++)
{
if (n == 0) ptr[n] = 1;
else ptr[n] = 0;
}
// Skip pubexp
ptr += 4;
// Skip modulus, prime1, prime2
ptr += (dwBitLen/8);
ptr += (dwBitLen/16);
ptr += (dwBitLen/16);
// Convert exponent1 to 1
for (n = 0; n < (dwBitLen/16); n++)
{
if (n == 0) ptr[n] = 1;
else ptr[n] = 0;
}
// Skip exponent1
ptr += (dwBitLen/16);
// Convert exponent2 to 1
for (n = 0; n < (dwBitLen/16); n++)
{
if (n == 0) ptr[n] = 1;
else ptr[n] = 0;
}
// Skip exponent2, coefficient
ptr += (dwBitLen/16);
ptr += (dwBitLen/16);
// Convert privateExponent to 1
for (n = 0; n < (dwBitLen/8); n++)
{
if (n == 0) ptr[n] = 1;
else ptr[n] = 0;
}
// Import the exponent-of-one private key.
if (!CryptImportKey(*hProv, keyblob, dwkeyblob, 0, 0, hPrivateKey))
{
TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
__leave;
}
TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey TRUE",NULL);
fReturn = TRUE;
}
__finally
{
if (keyblob) LocalFree(keyblob);
if (!fReturn)
{
if (*hPrivateKey) CryptDestroyKey(*hPrivateKey);
if (*hProv) CryptReleaseContext(*hProv, 0);
}
}
return fReturn;
}
/*
%--------------------------------------------------------------------------
% ImportPlainSessionBlob
%
% ImportPlainSessionBlob is used to import a key of session in light in a provider
% microsoft
%
% Parameters of entry :
% IN hProv handle to the provider
% IN hPrivateKey handle to the private key
% IN dwAlgId Algo ID
% IN pbKeyMaterial key
% IN dwKeyMaterial length of the key
% IN handle to the sessionKey
%
% return : TRUE if the operation occurred well, FALSE if not
%---------------------------------------------------------------------------
*/
BOOL HandleContainer::ImportPlainSessionBlob(HCRYPTPROV hProv,
HCRYPTKEY hPrivateKey,
ALG_ID dwAlgId,
LPBYTE pbKeyMaterial ,
DWORD dwKeyMaterial ,
HCRYPTKEY *hSessionKey)
{
BOOL fResult;
BOOL fReturn = FALSE;
BOOL fFound = FALSE;
LPBYTE pbSessionBlob = NULL;
DWORD dwSessionBlob, dwSize, n;
DWORD dwPublicKeySize;
DWORD dwProvSessionKeySize;
ALG_ID dwPrivKeyAlg;
LPBYTE pbPtr;
DWORD dwFlags = CRYPT_FIRST;
PROV_ENUMALGS_EX ProvEnum;
HCRYPTKEY hTempKey = 0;
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob BEGIN",NULL);
__try
{
// Double check to see if this provider supports this algorithm
// and key size
do
{
dwSize = sizeof(ProvEnum);
fResult = CryptGetProvParam(hProv, PP_ENUMALGS_EX, (LPBYTE)&ProvEnum,
&dwSize, dwFlags);
if (!fResult) break;
dwFlags = 0;
if (ProvEnum.aiAlgid == dwAlgId) fFound = TRUE;
} while (!fFound);
if (!fFound){
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
// We have to get the key size(including padding)
// from an HCRYPTKEY handle. PP_ENUMALGS_EX contains
// the key size without the padding so we can't use it.
if(dwAlgId==CALG_RC2 && dwKeyMaterial==5)
{
fResult = CryptGenKey(hProv, dwAlgId, CRYPT_NO_SALT, &hTempKey);
if (!fResult){
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
}
else
{
fResult = CryptGenKey(hProv, dwAlgId, 0, &hTempKey);
if (!fResult){
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
}
/*fResult = CryptGenKey(hProv, dwAlgId, 0, &hTempKey);
if (!fResult){
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}*/
dwSize = sizeof(DWORD);
fResult = CryptGetKeyParam(hTempKey, KP_KEYLEN, (LPBYTE)&dwProvSessionKeySize,
&dwSize, 0);
if (!fResult){
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
CryptDestroyKey(hTempKey);
hTempKey = 0;
// Our key is too big, leave
if ((dwKeyMaterial * 8) > dwProvSessionKeySize){
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
// Get private key's algorithm
dwSize = sizeof(ALG_ID);
fResult = CryptGetKeyParam(hPrivateKey, KP_ALGID, (LPBYTE)&dwPrivKeyAlg, &dwSize, 0);
if (!fResult){
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
// Get private key's length in bits
dwSize = sizeof(DWORD);
fResult = CryptGetKeyParam(hPrivateKey, KP_KEYLEN, (LPBYTE)&dwPublicKeySize, &dwSize, 0);
if (!fResult){
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
// calculate Simple blob's length
dwSessionBlob = (dwPublicKeySize/8) + sizeof(ALG_ID) + sizeof(BLOBHEADER);
// allocate simple blob buffer
pbSessionBlob = (LPBYTE)LocalAlloc(LPTR, dwSessionBlob);
if (!pbSessionBlob) {
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
pbPtr = pbSessionBlob;
// SIMPLEBLOB Format is documented in SDK
// Copy header to buffer
((BLOBHEADER *)pbPtr)->bType = SIMPLEBLOB;
((BLOBHEADER *)pbPtr)->bVersion = 2;
((BLOBHEADER *)pbPtr)->reserved = 0;
((BLOBHEADER *)pbPtr)->aiKeyAlg = dwAlgId;
pbPtr += sizeof(BLOBHEADER);
// Copy private key algorithm to buffer
*((DWORD *)pbPtr) = dwPrivKeyAlg;
pbPtr += sizeof(ALG_ID);
// Place the key material in reverse order
for (n = 0; n < dwKeyMaterial; n++)
{
pbPtr[n] = pbKeyMaterial[dwKeyMaterial-n-1];
}
// 3 is for the first reserved byte after the key material + the 2 reserved bytes at the end.
dwSize = dwSessionBlob - (sizeof(ALG_ID) + sizeof(BLOBHEADER) + dwKeyMaterial+ 3);
pbPtr +=dwKeyMaterial+1;
// Generate random data for the rest of the buffer
// (except that last two bytes)
fResult = CryptGenRandom(hProv, dwSize, pbPtr);
if (!fResult){
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
for (n = 0; n < dwSize; n++)
{
if (pbPtr[n] == 0) pbPtr[n] = 1;
}
pbSessionBlob[dwSessionBlob - 2] = 2;
if(dwAlgId==CALG_RC2 && dwKeyMaterial==5)
{
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob CALG RC2 40 Bits",NULL);
fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob,
hPrivateKey, CRYPT_EXPORTABLE|CRYPT_NO_SALT, hSessionKey);
if (!fResult) {
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
}
else{
fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob,
hPrivateKey, CRYPT_EXPORTABLE, hSessionKey);
if (!fResult) {
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}
}
/*fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob,
hPrivateKey, CRYPT_EXPORTABLE, hSessionKey);
if (!fResult) {
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
__leave;
}*/
TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob TRUE",NULL);
fReturn = TRUE;
}
__finally
{
if (hTempKey) CryptDestroyKey(hTempKey);
if (pbSessionBlob) LocalFree(pbSessionBlob);
}
return fReturn;
}
/*
%--------------------------------------------------------------------------
% ExportPlainSessionBlob
%
% ExportPlainSessionBlob is used to export a key of session in light
%
% Parameters of entry :
% IN hPublicKey handle to the public key
% IN hSessionKey handle to the session key
% IN pbKeyMaterial key
% IN dwKeyMaterial length of the key
%
% return : TRUE if the operation occurred well, FALSE if not
%---------------------------------------------------------------------------
*/
BOOL HandleContainer::ExportPlainSessionBlob(HCRYPTKEY hPublicKey,
HCRYPTKEY hSessionKey,
LPBYTE *pbKeyMaterial ,
DWORD *dwKeyMaterial )
{
BOOL fReturn = FALSE;
BOOL fResult;
DWORD dwSize, n;
LPBYTE pbSessionBlob = NULL;
DWORD dwSessionBlob;
LPBYTE pbPtr;
__try
{
*pbKeyMaterial = NULL;
*dwKeyMaterial = 0;
fResult = CryptExportKey(hSessionKey, hPublicKey, SIMPLEBLOB,
0, NULL, &dwSessionBlob );
if (!fResult) __leave;
pbSessionBlob = (LPBYTE)LocalAlloc(LPTR, dwSessionBlob );
if (!pbSessionBlob) __leave;
fResult = CryptExportKey(hSessionKey, hPublicKey, SIMPLEBLOB,
0, pbSessionBlob , &dwSessionBlob );
if (!fResult) __leave;
// Get session key size in bits
dwSize = sizeof(DWORD);
fResult = CryptGetKeyParam(hSessionKey, KP_KEYLEN, (LPBYTE)dwKeyMaterial, &dwSize, 0);
if (!fResult) __leave;
// Get the number of bytes and allocate buffer
*dwKeyMaterial /= 8;
*pbKeyMaterial = (LPBYTE)LocalAlloc(LPTR, *dwKeyMaterial);
if (!*pbKeyMaterial) __leave;
// Skip the header
pbPtr = pbSessionBlob;
pbPtr += sizeof(BLOBHEADER);
pbPtr += sizeof(ALG_ID);
// We are at the beginning of the key
// but we need to start at the end since
// it's reversed
pbPtr += (*dwKeyMaterial - 1);
// Copy the raw key into our return buffer
for (n = 0; n < *dwKeyMaterial; n++)
{
(*pbKeyMaterial)[n] = *pbPtr;
pbPtr--;
}
fReturn = TRUE;
}
__finally
{
if (pbSessionBlob) LocalFree(pbSessionBlob);
if ((!fReturn) && (*pbKeyMaterial ))
{
LocalFree(*pbKeyMaterial );
*pbKeyMaterial = NULL;
*dwKeyMaterial = 0;
}
}
return fReturn;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -