3

我不知道我是否遗漏了什么,我正在尝试将遗留代码移动到 Ngen,我必须使用 Key Storage Provider aka 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, &paramInfo, 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);
4

0 回答 0