encryption - 如何使用 Windows CryptoAPI 中的原始十六进制密钥值为 CryptDecrypt 创建对称密钥?
问题描述
经过大量的反复试验,我能够使用 Windows 使用 AES-256 密钥成功加密文件CryptoAPI
。
加密程序执行以下操作:
- 将块长度固定为 128 位 (
AES
) - 生成 AES-256-CBC 密钥 (
CryptGenKey
) - 使用此密钥加密文件 (
CryptEncrypt
)
现在为了解密文件,我想使用原始十六进制值格式的密钥。例如,我有这个键:
76FD3DBDFA2AA07113A227D9E0311DC5BC7FA78A7E4FC3CE63919B9C49DC4F06
(请注意,此密钥仅作为示例在线随机生成,不用于任何地方保护任何东西)
我所拥有的只是密钥的原始十六进制值,如上所示。所以我需要能够将它提供给CryptDecrypt
函数并解密数据。问题是:
CryptDecrypt 期望密钥作为 HCRYPTKEY 数据类型发送。但我所拥有的只是一个以这种格式存储的密钥:
wchar_t* key = argv[1] //reading the key in hex format as an argument
我试过的:
CryptDeriveKey从基值派生 HCRYPTKEY 格式的密钥。但是,CryptDeriveKey 不会接受我目前拥有的十六进制值格式的密钥,因为它反过来需要 HCRYPTHASH 格式的密钥。
在这一点上,我不确定如何使用我拥有的原始十六进制值作为 CryptDecrypt 解密数据的密钥。我知道这是可能的,我只是不知道如何到达那里。
由于我不会进入的原因,我必须从我拥有的原始十六进制值中获取密钥(与任何其他密钥格式,如字节数组相反)并将其提供CryptDecrypt
给解密数据。
解决方案
您应该使用CryptImportKey 函数导入密钥。
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();
}
推荐阅读
- c# - 从缓冲区数组创建 jpeg 图像
- android - android app 以编程方式安装 targetSDK 24 , compileSDK 28 , minSDK 19
- google-apps-script - 修改 Google Cloud Datastore API 请求的响应大小
- c++ - 存储指向专用模板函数的指针的值
- javascript - 反应错误:插件/预设文件不允许导出对象,只有功能
- javascript - 循环中的异步获取
- xcode - 不要在崩溃时重新启动 Xcode 测试
- macos - 当我们只需要传递一个参数时,有什么方法可以将可选参数传递给苹果脚本中的处理程序
- sql - Qlikview 按月生成 qvd
- python - 用 numpy 计算坐标的新位置