我有一些问题。我需要使用CryptoAPI生成和导出对称密钥。
if(CryptAcquireContext(&hCryptProv_AES, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0))
{
_tprintf(
TEXT("A cryptographic provider has been acquired. \n"));
}
else
{
DWORD d = GetLastError();
std::cout<<"";
return -1;
}
if (!CryptGenKey(hCryptProv_AES,CALG_AES_256,CRYPT_EXPORTABLE,&hSessionKey_AES))
{
DWORD d = GetLastError();
std::cout<<"";
return -1;
}
else
{
std::cout<<"OK";
}
// Export key
BYTE keybuf[ 1024 ], buffer[ 1024 ];
DWORD i, keylen = sizeof( buffer );
struct ekb
{
PUBLICKEYSTRUC hdr;
ALG_ID algId;
BYTE key[1];
} *encKey = (struct ekb *)buffer;
bool bbb = CryptExportKey(hSessionKey_AES, NULL, SIMPLEBLOB, 0, (BYTE *)encKey, &keylen);
DWORD f = GetLastError();
但不能使用AES密钥。 我如何解决这个问题,请帮忙。我如何获得AES密钥?
UPDATE 例如,我使用下一个代码,可以获得公共RSA密钥。
char * base_txt = "Test text";
char * enc_text = "";
if(CryptAcquireContext(&hCryptProv_RSA, NULL, MS_ENHANCED_PROV , PROV_RSA_FULL, 0))
{
_tprintf(
TEXT("A cryptographic provider has been acquired. \n"));
}
else
{
DWORD d = GetLastError();
std::cout<<"";
return -1;
}
if (!CryptGenKey(hCryptProv_RSA,AT_KEYEXCHANGE,1024<<16,&hSessionKey))
{
DWORD d = GetLastError();
std::cout<<"";
return -1;
}
RSAPubKey1024 key;
DWORD dwLen=sizeof(RSAPubKey1024);
// Export key
bool bb = CryptExportKey(hSessionKey,NULL,PUBLICKEYBLOB,0,(BYTE *)&key,&dwLen);
更新2 导出后我导入密钥并尝试加密和解密
HCRYPTPROV hCryptProv_AES22;
if (CryptAcquireContext(&hCryptProv_AES22, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0))
{
printf("A cryptographic provider has been acquired.\r\n");
}
else
{
DWORD d = GetLastError();
return -1;
}
int iii = CryptImportKey(hCryptProv_AES22,(BYTE *)&exportKey_AES,keylen,NULL,NULL,&hSessionKey_AES2);
if(CryptSetKeyParam(hSessionKey_AES2,KP_IV, exportKey_AES, 0))
{
BYTE encryptedMessage[1024];
const char * message = "Decryption Works -- using multiple blocks";
BYTE messageLen = (BYTE)strlen(message);
memcpy(encryptedMessage, message, messageLen);
DWORD encryptedMessageLen = messageLen;
CryptEncrypt(hSessionKey_AES2, NULL, TRUE, 0, encryptedMessage, &encryptedMessageLen, sizeof(encryptedMessage));
CryptDecrypt(hSessionKey_AES2,NULL,TRUE,0,encryptedMessage, &encryptedMessageLen);
}
答案 0 :(得分:3)
CryptExportKey
有一个限制。 要求以加密形式导出非公钥。导出公共部分或RSA密钥对时,可以使用第二个CryptExportKey
参数NULL
并以未加密的形式导出密钥。但是,对于必须指定非null hExpKey
参数的对称密钥,您不能执行相同的操作。
如果指定hExpKey
参数,则代码有效,请参阅示例:
#include <Windows.h>
#include <cstdio>
int main(int argc, char *argv[])
{
// Create AES key
HCRYPTPROV hCryptProv_AES;
if (CryptAcquireContext(&hCryptProv_AES, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0))
{
printf("A cryptographic provider has been acquired.\r\n");
}
else
{
DWORD d = GetLastError();
return -1;
}
HCRYPTKEY hSessionKey_AES;
if (!CryptGenKey(hCryptProv_AES, CALG_AES_256, CRYPT_EXPORTABLE, &hSessionKey_AES))
{
DWORD d = GetLastError();
return -1;
}
// Create RSA key to encrypt AES one
HCRYPTKEY hSessionKey;
if (!CryptGenKey(hCryptProv_AES, AT_KEYEXCHANGE, 1024 << 16, &hSessionKey))
{
DWORD d = GetLastError();
return -1;
}
// Export key
DWORD keylen;
BOOL ok = CryptExportKey(hSessionKey_AES, hSessionKey, SIMPLEBLOB, 0, NULL, &keylen);
if (ok == FALSE)
{
DWORD d = GetLastError();
return -1;
}
BYTE *encKey = (BYTE *)malloc(keylen);
ok = CryptExportKey(hSessionKey_AES, hSessionKey, SIMPLEBLOB, 0, encKey, &keylen);
if (ok == FALSE)
{
DWORD d = GetLastError();
return -1;
}
else
printf("A cryptographic key export succeeded.\r\n");
return 0;
}
如果您想进行密钥交换(假设您希望Alice向Bob发送她的AES密钥),您必须执行以下步骤:
CryptImportKey
导入它)。导入密钥时,将hPubKey
参数设置为非NULL值,实际上将其设置为Bob的密钥句柄,否则导入将失败,因为AES密钥已加密。