Я не знаю, пропустил ли я что-то, я пытаюсь перенести устаревший код в Ngen, и мне нужно использовать поставщик хранилища ключей, также известный как NCrypt.
Я пытался экспортировать ключ AES, первое, что я обнаружил, было то, что
NCryptExport при условии, что наилучшим способом является экспорт ключа с использованием pkcs7, и при условии, что если я добавлю ключ экспорта во второй параметр, то это будет ключ, используемый для кода pkc7
Я получаю сообщение об ошибке NTE_INVALID_PARAMETER
если я пытаюсь использовать NCryptExport с NCRPT_OPAQUETRANSPORT_KEY, я получаю NTE_INVALID_KEY_STATE
такой код
NCRYPT_PROV_HANDLE hProv = NULL;
SECURITY_STATUS pState = 0;
pState = NCryptOpenStorageProvider(&hProv, NULL, 0);
if (pState != ERROR_SUCCESS)
{
_wprintf_p(L"NCryptOpenStorageProvider (%X). ", pState);
return -1;
}
NCRYPT_KEY_HANDLE hContainerKey = 0;
pState = NCryptCreatePersistedKey(hProv, &hContainerKey, BCRYPT_RSA_ALGORITHM, L"TEST", AT_KEYEXCHANGE, 0);
if (pState == ERROR_SUCCESS)
{
int KeyLength = 2048;
pState = NCryptSetProperty(hContainerKey, NCRYPT_LENGTH_PROPERTY, (PBYTE) &KeyLength, sizeof(int), 0);
int allowPlainExport = NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
pState = NCryptSetProperty(hContainerKey, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE) &allowPlainExport, sizeof(int), 0);
}
else if(pState == NTE_EXITS)
{
pState = NCryptOpenKey(hProv, &hContainerKey, L"Test Key 2", AT_KEYEXCHANGE, 0);
}
else{ NCryptFreeObject(hProv);
return -1;}
pState = NCryptFinalizeKey(hContainerKey, NCRYPT_WRITE_KEY_TO_LEGACY_STORE_FLAG);
BYTE* blob = NULL;
NCRYPT_KEY_HANDLE hKey = NULL;
// Create a temporary key by setting null on the name as per documentation
pState = NCryptCreatePersistedKey(hProv,&hKey, BCRYPT_AES_ALGORITHM , NULL, 0 , 0);
if (pState != ERROR_SUCCESS)
{
_wprintf_p(L"NCryptCreatePersistedKey (%X). ", pState);
NCryptFreeObject(hContainerKey);
NCryptFreeObject(hProv);
return -1;
}
int KeyLength = 256;
int blockLength = 128 / 8; // AES does support 256 block length !
LPCTSTR chainMode = BCRYPT_CHAIN_MODE_ECB; // Just for testing
DWORD allowExport = NCRYPT_ALLOW_EXPORT_FLAG;
pState = NCryptSetProperty(hKey, NCRYPT_LENGTH_PROPERTY, (PBYTE)&KeyLength, sizeof(int), 0);
pState = NCryptSetProperty(hKey, NCRYPT_BLOCK_LENGTH_PROPERTY, (PBYTE)&blockLength, sizeof(int), 0);
pState = NCryptSetProperty(hKey, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)&allowExport, sizeof(int), 0);
pState = NCryptFinalizeKey(hKey, 0);
pState = NCryptSetProperty(hKey, NCRYPT_CHAINING_MODE_PROPERTY, (PBYTE)chainMode, _tcslen(chainMode) * sizeof(TCHAR), 0);
//TEST key
LPSTR Secret = "Secret !Secret !Secret !Secret !";
blobSize = 0;
pState = NCryptEncrypt(hKey, (PBYTE) Secret, strlen(Secret), NULL,NULL, blobSize,&blobSize, NCRYPT_NO_PADDING_FLAG);
if (pState == ERROR_SUCCESS)
{// if you are here the key looks fine
blob = new BYTE[blobSize];
pState = NCryptEncrypt(hKey, (PBYTE)Secret, strlen(Secret), NULL, blob, blobSize, &blobSize, 0);
DWORD plainSize = 0;
pState = NCryptDecrypt(hKey, (PBYTE)blob, blobSize, NULL, NULL, plainSize, &plainSize, 0);
BYTE* plain = new BYTE[plainSize];
pState = NCryptDecrypt(hKey, (PBYTE)blob, blobSize, NULL, plain, plainSize, &plainSize, 0);
delete[]plain;
delete[] blob;
// the result should be the same Secret !
}
//Open a certificate store handle. For the purposes of this test, it does not matter what certificates are there.
//After getting this to work at least once, will look at actually selecting the certificates.
HCERTSTORE hSysStore = NULL;
if (hSysStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM, // The store provider type
0, // The encoding type is not needed
NULL, // Use the default HCRYPTPROV
CERT_SYSTEM_STORE_CURRENT_USER, // Set the store location in a registry location
L"MY" // The store name as a Unicode string
))
{
}
else
{
NCryptFreeObject(hKey);
NCryptFreeObject(hContainerKey);
NCryptFreeObject(hProv);
return -1;
}
//Export the certificate store blob. Exporting as a store, saving to memory.
CERT_BLOB certStoreBlob;
certStoreBlob.pbData = nullptr;
certStoreBlob.cbData = 0;
BOOL result = CertSaveStore(hSysStore, 0, CERT_STORE_SAVE_AS_STORE, CERT_STORE_SAVE_TO_MEMORY, &certStoreBlob, 0);
if (!result)
{
DWORD error = GetLastError();
CertCloseStore(hSysStore, CERT_CLOSE_STORE_CHECK_FLAG);
NCryptFreeObject(hKey);
NCryptFreeObject(hContainerKey);
NCryptFreeObject(hProv);
return -1;
}
vector<BYTE> certBlobData(certStoreBlob.cbData);
certStoreBlob.pbData = certBlobData.data();
result = CertSaveStore(hSysStore, 0, CERT_STORE_SAVE_AS_STORE, CERT_STORE_SAVE_TO_MEMORY, &certStoreBlob, 0);
if (!result)
{
DWORD error = GetLastError();
CertCloseStore(hSysStore, CERT_CLOSE_STORE_CHECK_FLAG);
NCryptFreeObject(hKey);
NCryptFreeObject(hContainerKey);
NCryptFreeObject(hProv);
return -1;
}
CertCloseStore(hSysStore, CERT_CLOSE_STORE_CHECK_FLAG);
blobSize = 0;
NCryptBuffer *PKCS7 = new NCryptBuffer[2];
PKCS7[0].BufferType = NCRYPTBUFFER_PKCS_ALG_OID;
PKCS7[0].pvBuffer = szOID_RSAES_OAEP;
PKCS7[0].cbBuffer = strlen(szOID_RSAES_OAEP);
PKCS7[1].BufferType = NCRYPTBUFFER_CERT_BLOB;
PKCS7[1].pvBuffer = NULL;
PKCS7[1].cbBuffer = 0;
NCryptBufferDesc paramInfo;// = new NCryptBufferDesc[3];
paramInfo.ulVersion = NCRYPTBUFFER_VERSION;
paramInfo.cBuffers = 2;
paramInfo.pBuffers = PKCS7;
pState = NCryptExportKey(hKey, hContainerKey, NCRYPT_PKCS7_ENVELOPE_BLOB, ¶mInfo, NULL, blobSize, &blobSize, 0);
if (pState != ERROR_SUCCESS)
{
_wprintf_p(L"NCryptExportKey AES key (%X). ", pState);
NCryptFreeObject(hKey);
NCryptFreeObject(hContainerKey);
NCryptFreeObject(hProv);
return -1;
}
blob = new BYTE[blobSize];
NCryptExportKey(hKey, hContainerKey, NCRYPT_PKCS7_ENVELOPE_BLOB, &parmInfo, blob, blobSize, &blobSize, 0);
NCryptFreeObject(hKey);
NCryptFreeObject(hContainerKey);
NCryptFreeObject(hProv);
Задача ещё не решена.
Других решений пока нет …