1. Как подписать с закрытым ключом RSA? ( решено )
Я следовал этому образцу , чтобы подписать данные закрытым ключом. Я только резервирую функции ha sh и подписываю их, и использую закрытый ключ ECDSA P-256, как в примере.
Вот мои шаги, и программа отлично работает:
BCryptOpenAlgorithmProvider()
- Ха sh некоторые данные
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, который имеет закрытый ключ (ECDSA P-256) в My
хранилище сертификатов.
Вот мои шаги и программа работает только при первом запуске. Не удалось в CryptAcquireCertificatePrivateKey()
с NTE_BAD_KEYSET error
BCryptOpenAlgorithmProvider()
- Ха sh некоторые данные
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;
}
ОБНОВЛЕНИЕ2:
Код работает после удаления NCryptDeleteKey(hKey, 0)
. Я думаю, что этот API удаляет мой ключ E C! Но я не знаю, почему ключ RSA не удаляется?