如何使用Windows CryptoAPI中的原始十六进制密钥值为CryptDecrypt创建对称密钥?

时间:2019-06-06 20:56:46

标签: encryption cryptography cryptoapi

经过反复试验,我能够使用Windows CryptoAPI使用AES-256密钥成功加密文件。

加密程序执行以下操作:

  • 将块长度固定为128位(AES
  • 生成AES-256-CBC密钥(CryptGenKey
  • 使用此密钥(CryptEncrypt)加密文件

现在,为了解密文件,我想使用原始十六进制值格式的密钥。例如,我有以下键:

  

76FD3DBDFA2AA07113A227D9E0311DC5BC7FA78A7E4FC3CE63919B9C49DC4F06

(请注意,此密钥是随机的generated online,仅作为示例,并不在任何地方用于保护任何东西)

我所拥有的只是密钥的原始十六进制值,如上所示。因此,我需要能够将其提供给CryptDecrypt函数并解密数据。 问题是:

CryptDecrypt expects the key to be sent in as an HCRYPTKEY data type。但是我所拥有的只是以这种格式存储的密钥:

wchar_t* key = argv[1]  //reading the key in hex format as an argument

我尝试过的事情:

CryptDeriveKey可以从基本值中导出HCRYPTKEY格式的密钥。但是,CryptDeriveKey不会接受我目前使用的十六进制值格式的密钥,因为它反过来需要HCRYPTHASH格式的密钥。

这时,我不确定如何使用原始十六进制值作为CryptDecrypt解密数据的密钥。我知道这是可能的,我只是不知道如何到达那里。

出于我不愿讨论的原因,我必须从我拥有的原始十六进制值(与任何其他密钥格式(例如字节数组)相对)导出密钥,并将其提供给CryptDecrypt解密数据。

1 个答案:

答案 0 :(得分:1)

您应使用CryptImportKey function导入密钥。

BOOL CryptImportKey(
  HCRYPTPROV hProv,
  const BYTE *pbData,
  DWORD      dwDataLen,
  HCRYPTKEY  hPubKey,
  DWORD      dwFlags,
  HCRYPTKEY  *phKey
);

hProv-通过CryptAcquireContext函数获得的CSP的句柄。
hPubKey-您的情况必须为0。
dwFlags-您的情况必须为0。
phKey-CryptDecrypt期望的结果密钥。

这是一些棘手的部分。 pbData 必须包含BLOBHEADER结构,后跟键值。

typedef struct _PUBLICKEYSTRUC {
  BYTE   bType;
  BYTE   bVersion;
  WORD   reserved;
  ALG_ID aiKeyAlg;
} BLOBHEADER, PUBLICKEYSTRUC;

bType = PLAINTEXTKEYBLOB (0x08) - in your case  
bVersion = CUR_BLOB_VERSION (0x02) 
reserved = 0  
aiKeyAlg = algorithm id which you used in CryptGenKey

示例代码:

BYTE key_value[] = { 0x76, 0xFD, 0x3D, 0xBD, 0xFA, 0x2A, 0xA0, 0x71, 0x13, 0xA2, 0x27, 0xD9, 0xE0, 0x31, 0x1D, 0xC5, 
    0xBC, 0x7F, 0xA7, 0x8A, 0x7E, 0x4F, 0xC3, 0xCE, 0x63, 0x91, 0x9B, 0x9C, 0x49, 0xDC, 0x4F, 0x06 };
BLOBHEADER bh;
bh.bType = PLAINTEXTKEYBLOB;
bh.bVersion = CUR_BLOB_VERSION;
bh.reserved = 0;
bh.aiKeyAlg = CALG_AES_256;

DWORD dwDataLen = sizeof(key_value) + sizeof(bh);
BYTE* pbData = (BYTE*)malloc(dwDataLen);
BYTE* ptr = pbData;
memcpy(ptr, (BYTE*)&bh, sizeof(bh));
ptr += sizeof(bh);
memcpy(ptr, key_value, sizeof(key_value));
if (!CryptImportKey(hProv, pbData, dwDataLen, 0, 0, &hKey)) {
    return GetLastError();
}