1。如何使用RSA私钥签名?(已解决)
我遵循此sample用私钥对数据签名。我只保留哈希和符号函数,并使用ECDSA P-256私钥,例如示例。
这是我的步骤,程序运行正常:
BCryptOpenAlgorithmProvider()
NCryptOpenStorageProvider()
NCryptCreatePersistedKey()
NCryptFinalizeKey()
NCryptSignHash()
NCryptSignHash()
我尝试使用RSA私钥进行签名,将NCRYPT_ECDSA_P256_ALGORITHM
替换为NCRYPT_RSA_ALGORITHM
和NCRYPT_RSA_SIGN_ALGORITHM
,但是在第二NCryptSignHash()
中使用NTE_INVALID_PARAMETER
失败了。
//create a persisted key
if (FAILED(secStatus = NCryptCreatePersistedKey(
hProv,
&hKey,
NCRYPT_RSA_ALGORITHM,
L"my RSA key",
0,
0)))
{
wprintf(L"**** Error 0x%x returned by NCryptCreatePersistedKey\n", secStatus);
goto Cleanup;
}
2。为什么程序在首次运行后找不到私钥?
私钥是在程序中创建的,我尝试使用X509证书签名,该证书在My
证书存储区中具有私钥(ECDSA P-256)。
这是我的步骤,该程序只能在第一次运行时使用。它在CryptAcquireCertificatePrivateKey()
中以NTE_BAD_KEYSET error
失败了
BCryptOpenAlgorithmProvider()
CertOpenStore()
CertFindCertificateInStore()
CryptAcquireCertificatePrivateKey()
NCryptSignHash()
NCryptSignHash()
// Open the certificate store.
if (!(hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
CERT_STORE_NAME)))
{
MyHandleError(const_cast<LPTSTR>("The MY store could not be opened."));
}
swprintf(wMY_SIGNER_NAME, 100, L"%hs", MY_SIGNER_NAME);
if (pSignerCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
wMY_SIGNER_NAME,
NULL))
{
//_tprintf(TEXT("The signer's certificate was found.\n"));
}
else
{
MyHandleError(const_cast<LPTSTR>("Signer certificate not found."));
}
if (CryptAcquireCertificatePrivateKey(
pSignerCert,
CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG, NULL,
&hKey,
&dwKeySpec,
false))
{
printf("Get Priv OK\n");
}
else
{
if (GetLastError() == NTE_BAD_KEYSET)
printf("NTE_BAD_KEYSET\n");
}
更新:
if (FAILED(secStatus = NCryptSignHash(
hKey,
0,
pbHash,
cbHash,
NULL,
0,
&cbSignature,
0)))
{
wprintf(L"**** Error 0x%x returned by NCryptSignHash1\n", secStatus);
goto Cleanup;
}
//allocate the signature buffer
pbSignature = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbSignature);
if (NULL == pbSignature)
{
wprintf(L"**** memory allocation failed\n");
goto Cleanup;
}
if (FAILED(secStatus = NCryptSignHash(
hKey,
0,
pbHash,
cbHash,
pbSignature,
cbSignature,
&cbSignature,
0)))
{
wprintf(L"**** Error 0x%x returned by NCryptSignHash2\n", secStatus);
goto Cleanup;
}
UPDATE2:
代码在删除NCryptDeleteKey(hKey, 0)
之后起作用。我认为此API会删除我的EC密钥!但是我不知道为什么不能删除RSA密钥?