我需要在Windows中使用SHA256withRSA算法(带有SHA-256哈希函数的RSASSA-PKCS1-V1_5-SIGN)签署一些数据,并且我有一些验证错误。我想知道是否有人有尝试这样做的经验。
我正在做的总结:
CryptAcquireContextW with MS_ENH_RSA_AES_PROV and PROV_RSA_AES
CryptImportKey after running CryptStringToBinary on a pem and applying to that CryptDecodeObjectEx with PKCS_RSA_PRIVATE_KEY
CryptCreateHash with CALG_SHA_256
CryptHashData and CryptSignHash using AT_KEYEXCHANGE to use the imported key (AT_SIGNATURE didn't work)
如果您想要详细版本,请点击此处:
创建CSP
WCHAR const container[] = L"ContainerName";
HCRYPTPROV provider;
CryptAcquireContextW(
&provider,
container,
MS_ENH_RSA_AES_PROV,
PROV_RSA_AES,
0));
导入我的私钥
char const key_string[] = "-----BEGIN RSA PRIVATE KEY-----"
"<base64 encoded key>"
"-----END RSA PRIVATE KEY-----";
DWORD key_bytes_size;
BYTE* key_bytes;
CryptStringToBinaryA(
key_string,
0,
CRYPT_STRING_BASE64HEADER,
nullptr, &key_bytes_size,
nullptr, nullptr);
key_bytes = new BYTE[key_bytes_size];
CryptStringToBinaryA(
key_string,
0,
CRYPT_STRING_BASE64HEADER,
key_bytes, &key_bytes_size,
nullptr, nullptr);
DWORD key_blob_size;
BYTE* key_blob;
CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
PKCS_RSA_PRIVATE_KEY,
key_bytes, key_bytes_size,
0, nullptr,
nullptr, &key_blob_size);
key_blob = new BYTE[key_blob_size];
CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
PKCS_RSA_PRIVATE_KEY,
key_bytes, key_bytes_size,
0, nullptr,
key_blob, &key_blob_size);
HCRYPTKEY key_handle;
CryptImportKey(
provider, // The one I created before
key_blob, key_blob_size,
nullptr, 0,
&key_handle);
(我讨厌API如此冗长,特别是要求长度然后填充缓冲区的两步舞蹈) 完成此操作后,我会哈希并对我的数据进行签名:
char const data[] = "Stuff to sign";
HCRYPTHASH hash_handle;
CryptCreateHash(provider, CALG_SHA_256, 0, 0, &hash_handle);
DWORD data_length = std::strlen(data);
CryptHashData(
hash_handle,
reinterpret_cast<const BYTE*>(data), data_length,
0);
DWORD signature_size;
BYTE* signature;
CryptSignHash(
hash_handle,
AT_KEYEXCHANGE, // AT_SIGNATURE didn't work
nullptr, 0,
nullptr, signature_size);
signature = new BYTE[signature_size];
CryptSignHash(
hash_handle,
AT_KEYEXCHANGE, // AT_SIGNATURE didn't work
nullptr, 0,
signature, signature_size);
这会产生我想要的那种签名吗?我应该为AcquireContext调用设置不同的参数吗?