此代码是否(a)动态创建ECDSA密钥(b)签署哈希(c)将密钥保存到证书存储(d)检索密钥并验证签署的哈希。如果是这样的话,我想这是演示代码。
A) 是的。
B) 是的。
nullptr
/
NULL
可能被传递,使其成为一个短暂的关键。(它将其保存到“密钥存储”,而不是“证书存储”。
获取公钥数据(这是
openssl ec -in eckey.pem -pubout -outform der | xxd -g1
static const BYTE data[] =
{
'1', '2', '3', '4',
};
static const BYTE publicKey[] =
{
0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
0x42, 0x00, 0x04, 0x23, 0x63, 0xdd, 0x13, 0x1d,
0xa6, 0x5e, 0x89, 0x9a, 0x2e, 0x63, 0xe9, 0xe0,
0x5e, 0x50, 0xc8, 0x30, 0xd4, 0x99, 0x46, 0x62,
0xff, 0xe8, 0x83, 0xdb, 0x2b, 0x9a, 0x76, 0x7d,
0xcc, 0xab, 0xa2, 0xf0, 0x70, 0x81, 0xb5, 0x71,
0x1b, 0xe1, 0xde, 0xe9, 0x0d, 0xfc, 0x8d, 0xe1,
0x79, 0x70, 0xc2, 0xd9, 0x37, 0xa1, 0x6c, 0xd3,
0x45, 0x81, 0xf5, 0x2b, 0x8d, 0x59, 0xc9, 0xe9,
0x53, 0x2d, 0x13,
};
static const BYTE signature[] =
{
// r
0xc6, 0x4c, 0x14, 0x55, 0xfe, 0xc0, 0x2f, 0xe7,
0x4a, 0x25, 0x87, 0xe7, 0x0c, 0x10, 0x4e, 0x73,
0xf0, 0x28, 0x86, 0x18, 0x28, 0xae, 0xef, 0x4f,
0xe5, 0xa0, 0xcc, 0x7a, 0xa8, 0xe4, 0x1f, 0xbf,
// s
0x35, 0x9f, 0x23, 0xfd, 0xc3, 0xd6, 0x33, 0xfb,
0x52, 0x47, 0x9b, 0xef, 0x2b, 0x2a, 0x48, 0xa8,
0x6f, 0x37, 0x04, 0xd0, 0x8c, 0xc3, 0x49, 0x04,
0x21, 0x53, 0xb8, 0x3c, 0x9d, 0x8c, 0x6c, 0xf5,
};
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
int main()
{
NTSTATUS status = NTE_BAD_DATA;
int exitCode = ERROR_INVALID_FUNCTION;
BCRYPT_KEY_HANDLE importedPublicKey = nullptr;
PCERT_PUBLIC_KEY_INFO subjectPublicKeyInfo = (PCERT_PUBLIC_KEY_INFO)LocalAlloc(0, 2048);
BCRYPT_ALG_HANDLE sha256 = nullptr;
BCRYPT_HASH_HANDLE hHash = nullptr;
BYTE dataHash[256 >> 3];
DWORD structSize = 2048;
if (!CryptDecodeObject(
X509_ASN_ENCODING,
X509_PUBLIC_KEY_INFO,
publicKey,
sizeof(publicKey),
0,
subjectPublicKeyInfo,
&structSize))
{
wprintf(L"**** Error 0x%x returned by CryptDecodeObject\n", GetLastError());
goto Cleanup;
}
if (!CryptImportPublicKeyInfoEx2(
X509_ASN_ENCODING,
subjectPublicKeyInfo,
0,
nullptr,
&importedPublicKey))
{
wprintf(L"**** Error 0x%x returned by CryptImportPublicKeyInfoEx2\n", GetLastError());
goto Cleanup;
}
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&sha256, BCRYPT_SHA256_ALGORITHM, nullptr, 0)))
{
wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
goto Cleanup;
}
if (!NT_SUCCESS(status = BCryptCreateHash(sha256, &hHash, nullptr, 0, nullptr, 0, 0)))
{
wprintf(L"**** Error 0x%x returned by BCryptCreateHash\n", status);
goto Cleanup;
}
if (!NT_SUCCESS(status = BCryptHashData(hHash, (PUCHAR)data, sizeof(data), 0)))
{
wprintf(L"**** Error 0x%x returned by BCryptHashData\n", status);
goto Cleanup;
}
if (!NT_SUCCESS(status = BCryptFinishHash(hHash, (PUCHAR)dataHash, sizeof(dataHash), 0)))
{
wprintf(L"**** Error 0x%x returned by BCryptFinishHash\n", status);
goto Cleanup;
}
status = BCryptVerifySignature(
importedPublicKey,
nullptr,
(PUCHAR)dataHash,
sizeof(dataHash),
(PUCHAR)signature,
sizeof(signature),
0);
switch (status)
{
case STATUS_SUCCESS:
wprintf(L"Signature verified successfully\n");
exitCode = ERROR_SUCCESS;
break;
case STATUS_INVALID_SIGNATURE:
wprintf(L"Signature did not verify\n");
exitCode = ERROR_INVALID_DATA;
break;
default:
wprintf(L"**** Error 0x%x returned by BCryptVerifySignature\n", status);
goto Cleanup;
}
Cleanup:
if (hHash != nullptr)
BCryptDestroyHash(hHash);
if (sha256 != nullptr)
BCryptCloseAlgorithmProvider(sha256, 0);
if (importedPublicKey != nullptr)
BCryptDestroyKey(importedPublicKey);
LocalFree(subjectPublicKeyInfo);
return exitCode;
}