Microsoft KeyStorageProvider functionality is working on Windows10 but not working on Windows 7 and Windows 8

Munagala, Rekha 16 Reputation points
2022-04-07T10:50:42.437+00:00

I added the code as following:

errCode = NCryptOpenStorageProvider(&prov2, MS_KEY_STORAGE_PROVIDER, 0) ;
errCode = NCryptImportKey(prov2, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, &desc, &key2, blobexport, blobLen, NCRYPT_DO_NOT_FINALIZE_FLAG);
errCode = NCryptSetProperty(key2, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)(&policy2), sizeof(policy2), NCRYPT_PERSIST_FLAG) ;
errCode = NCryptFinalizeKey(key2, 0);

this code is failing in NCryptFinalizeKey(key2, 0);
It's failing only Windows 2007 and Windows 2008.

Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
10,985 questions
Windows 10 Security
Windows 10 Security
Windows 10: A Microsoft operating system that runs on personal computers and tablets.Security: The precautions taken to guard against crime, attack, sabotage, espionage, or another threat.
2,808 questions
{count} vote

3 answers

Sort by: Most helpful
  1. Munagala, Rekha 16 Reputation points
    2022-04-08T05:36:20.003+00:00

    This program is working for Windows 10 properly but on Windows 7 and Windows 8 and Windows 8.1 I am getting following error :

    NCryptFinalizeKey key2 Response Code:-2146893785

    Hi I am giving proper details below:

    NCRYPT_PROV_HANDLE prov = NULL;
    NCRYPT_KEY_HANDLE key = NULL;
    DWORD keyLength = 2048;
    DWORD blobLen = 0x1000;
    BYTE blobexport[0x1000] = {0};
    DWORD policy = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
    int errCode = 0;
    errCode = NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0) ;//creatingstorageProvider
    out<<"NCryptOpenStorageProvider "<<" Response Code:"<<errCode<<endl;

            errCode = NCryptCreatePersistedKey(prov, &key, NCRYPT_RSA_ALGORITHM, L"persist",0,NCRYPT_OVERWRITE_KEY_FLAG) ;//create and store key  
            out<<"NCryptCreatePersistedKey "<<" Response Code:"<<errCode<<endl;  
    
           errCode = NCryptSetProperty(key, NCRYPT_LENGTH_PROPERTY, (PBYTE)(&keyLength), sizeof(keyLength), NCRYPT_PERSIST_FLAG) ;//set length to store key  
            out<<"NCryptSetProperty "<<" Response Code1:"<<errCode<<endl;  
    
            errCode = NCryptSetProperty(key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)(&policy), sizeof(policy), NCRYPT_PERSIST_FLAG);//set export property  
            out<<"NCryptSetProperty "<<" Response Code2:"<<errCode<<endl;  
    
           errCode = NCryptFinalizeKey(key, 0);//Do finiliaze key  
            out<<"NCryptFinalizeKey "<<" Response Code:"<<errCode<<endl;  
    
            errCode = NCryptExportKey(key, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, NULL, blobexport, blobLen, &blobLen, 0) ;//exporting the key from keystorage  
            out<<"NCryptExportKey "<<" Response Code:"<<errCode<<endl;  
    
             
    //I am adding my own Values to the exported key blob from keys array  
    

    int keys[32] = "{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2',3','4','5','6'}"
    int keysincrementValues=0;
    for(int setValues =64;setValues<=96;setValues++)
    {
    blobexport[setValues]=keys[keysincrementValues]+3;//Assigning key values to blobexport
    keysincrementValues++;
    }
    keys[32]='\0';
    NCRYPT_PROV_HANDLE prov2 = NULL;
    NCRYPT_KEY_HANDLE key2 = NULL;
    DWORD policy2 = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;

            LPCWSTR name = L"importKey";  
            BCryptBuffer cb[1];  
            cb[0].BufferType = NCRYPTBUFFER_PKCS_KEY_NAME;  
            cb[0].pvBuffer = (void*)name;  
            cb[0].cbBuffer = lstrlenW(name) * 2 + 2;  
            NCryptBufferDesc desc;  
            desc.ulVersion = 0;  
            desc.pBuffers = cb;  
            desc.cBuffers = 1;  
            errCode = NCryptOpenStorageProvider(&prov2, MS_KEY_STORAGE_PROVIDER, 0) ;//creating onemore storage  
            out<<"NCryptOpenStorageProvider prov2 "<<" Response Code:"<<errCode<<endl;  
    
         errCode = NCryptImportKey(prov2, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, &desc, &key2, blobexport, blobLen, NCRYPT_DO_NOT_FINALIZE_FLAG);//Importing blobexport to key storage means the 32 keys will be present in RSA KEY  
            out<<"NCryptImportKey key2 "<<" Response Code:"<<errCode<<endl;  
    
             
            errCode = NCryptSetProperty(key2, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)(&policy2), sizeof(policy2), NCRYPT_PERSIST_FLAG) ;//We are setting the export policy  
            out<<"NCryptSetProperty key2 "<<" Response Code:"<<errCode<<endl;  
    
             
            errCode = NCryptFinalizeKey(key2, 0);//finalized the key.  
            out<<"NCryptFinalizeKey key2 "<<" Response Code:"<<errCode<<endl;// NCryptFinalizeKey key2  Response Code:-2146893785    
    

    //I am getting error for finiliazed key NCryptFinalizeKey key2 Response Code:-2146893785

    And also NCryptFinalizeKey api supported OS is below which is given in the Microsoft doc:
    Minimum supported client Windows Vista [desktop apps | UWP apps]
    Minimum supported server Windows Server 2008 [desktop apps | UWP apps]
    the Microsoft doc link is below:

    https://learn.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptfinalizekey


  2. Xiaopo Yang - MSFT 12,066 Reputation points Microsoft Vendor
    2022-04-13T06:39:14.85+00:00

    Hello,

    Welcome to Microsoft Q&A!

    @Munagala, Rekha I'm sorry to say Windows7 & Windows8 support has ended. You can use Window11 where the program works well.

    Thank you.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  3. Xiaopo Yang - MSFT 12,066 Reputation points Microsoft Vendor
    2022-05-23T05:15:20.57+00:00

    Please have a look at the following sample which worked on a Windows 7, 8 and 8.1 VM.

    #include <Windows.h>
    #include <wincrypt.h>
    #include <stdio.h>
    
    void PrintUsage();
    
    int main(int argc, char *argv[]) {
        NCRYPT_PROV_HANDLE prov = NULL;
        NCRYPT_KEY_HANDLE key = NULL;
        NCRYPT_PROV_HANDLE prov2 = NULL;
        NCRYPT_KEY_HANDLE key2 = NULL;
        HANDLE hFile = INVALID_HANDLE_VALUE;
        DWORD dwWritten;
        DWORD dwRead;
        DWORD keyLength = 2048;
        DWORD blobLen = 0x1000;
        BYTE blobexport[0x1000] = { 0 };
        DWORD policy = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
        DWORD policy2 = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
        int errCode = 0;
        BOOL fCreateKey = TRUE;
        BOOL fResult;
        LPCWSTR name = L"importKey";
        NCryptBuffer cb;
        cb.BufferType = NCRYPTBUFFER_PKCS_KEY_NAME;
        cb.pvBuffer = (void*)name;
        cb.cbBuffer = lstrlenW(name) * 2 + 2;
        NCryptBufferDesc desc;
        desc.ulVersion = 0;
        desc.pBuffers = &cb;
        desc.cBuffers = 1;
    
        if (argc != 2)
        {
            PrintUsage();
            return 0;
        }
    
        if (argv[1][0] == 'c' || argv[1][0] == 'C')
        {
            fCreateKey = TRUE;
        }
        else if (argv[1][0] == 'i' || argv[1][0] == 'I')
        {
            fCreateKey = FALSE;
        }
        else
        {
            PrintUsage();
            return 0;
        }
        
        if (fCreateKey)
        {
            errCode = NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0);//creatingstorageProvider
            if (errCode != ERROR_SUCCESS)
            {
                printf("NCryptOpenStorageProvider failed. %x\n", errCode);
                return 0;
            }
    
            errCode = NCryptCreatePersistedKey(prov, &key, NCRYPT_RSA_ALGORITHM, L"persist", 0, NCRYPT_OVERWRITE_KEY_FLAG);//create and store key
            if (errCode != ERROR_SUCCESS)
            {
                printf("NCryptCreatePersistedKey failed. %x\n", errCode);
                return 0;
            }
    
            errCode = NCryptSetProperty(key, NCRYPT_LENGTH_PROPERTY, (PBYTE)(&keyLength), sizeof(keyLength), NCRYPT_PERSIST_FLAG);//set length to store key
            if (errCode != ERROR_SUCCESS)
            {
                printf("NCryptSetProperty(NCRYPT_LENGTH_PROPERTY) failed. %x\n", errCode);
                return 0;
            }
    
            errCode = NCryptSetProperty(key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)(&policy), sizeof(policy), NCRYPT_PERSIST_FLAG);//set export property
            if (errCode != ERROR_SUCCESS)
            {
                printf("NCryptSetProperty(NCRYPT_EXPORT_POLICY_PROPERTY) failed. %x\n", errCode);
                return 0;
            }
    
            errCode = NCryptFinalizeKey(key, 0);//Do finiliaze key
            if (errCode != ERROR_SUCCESS)
            {
                printf("NCryptFinalizeKey failed. %x\n", errCode);
                return 0;
            }
    
            errCode = NCryptExportKey(key, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, NULL, blobexport, blobLen, &blobLen, 0);//exporting the key from keystorage
            if (errCode != ERROR_SUCCESS)
            {
                printf("NCryptExportKey failed. %x\n", errCode);
                return 0;
            }
    
            hFile = CreateFileA("PKCS8_PrivaKey", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, NULL, NULL);
            if (hFile == INVALID_HANDLE_VALUE)
            {
                printf("CreateFile failed. %d\n", GetLastError());
                return 0;
            }
    
            fResult = WriteFile(hFile, blobexport, blobLen, &dwWritten, NULL);
            if (!fResult)
            {
                printf("WriteFile failed. %d\n", GetLastError());
                return 0;
            }
    
            printf("PKCS8_PrivKey file saved.\n");
            CloseHandle(hFile);
        }
        else
        {
            hFile = CreateFileA("PKCS8_PrivaKey", GENERIC_READ, 0, NULL, OPEN_EXISTING, NULL, NULL);
            if (hFile == INVALID_HANDLE_VALUE)
            {
                printf("CreateFile failed. %d\n", GetLastError());
                return 0;
            }
    
            blobLen = GetFileSize(hFile, NULL);
            if (blobLen == INVALID_FILE_SIZE)
            {
                printf("GetFileSize failed. %d\n", GetLastError());
                return 0;
            }
    
            fResult = ReadFile(hFile, blobexport, blobLen, &dwRead, NULL);
            if (!fResult)
            {
                printf("ReadFile failed. %d\n", GetLastError());
                return 0;
            }
    
            CloseHandle(hFile);
    
            errCode = NCryptOpenStorageProvider(&prov2, MS_KEY_STORAGE_PROVIDER, 0);//creating onemore storage
            if (errCode != ERROR_SUCCESS)
            {
                printf("NCryptOpenStorageProvider failed. %x\n", errCode);
                return 0;
            }
    
            errCode = NCryptImportKey(prov2, NULL, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, &desc, &key2, blobexport, blobLen, NCRYPT_DO_NOT_FINALIZE_FLAG);//Importing blobexport to key storage means the 32 keys will be present in RSA KEY
            if (errCode != ERROR_SUCCESS)
            {
                printf("NCryptImportKey failed. %x\n", errCode);
                return 0;
            }
    
            errCode = NCryptSetProperty(key2, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)(&policy2), sizeof(policy2), NCRYPT_PERSIST_FLAG);//We are setting the export policy
            if (errCode != ERROR_SUCCESS)
            {
                printf("NCryptSetProperty(NCRYPT_EXPORT_POLICY_PROPERTY) failed. %x\n", errCode);
                return 0;
            }
    
            errCode = NCryptFinalizeKey(key2, 0);//finalized the key. NCryptFinalizeKey key2  Response Code:-2146893785  
            if (errCode != ERROR_SUCCESS)
            {
                printf("NCryptFinalizeKey failed. %x\n", errCode);
                return 0;
            }
    
            printf("Successfully imported PKCS8 key\n");
        }
    
        if (key != NULL) NCryptFreeObject(key);
        if (prov != NULL) NCryptFreeObject(prov);
        if (key2 != NULL) NCryptFreeObject(key2);
        if (prov2 != NULL) NCryptFreeObject(prov2);
        return 1;
    }
    
    void PrintUsage()
    {
        printf("Usage: NCryptTest [<c>reate key|[i]mport key]");
    }