SHA-2 Support – Migrate your CA from CSP to KSP


In this blog post, I will be talking about [Migrating a Certification Authority Key from a Cryptographic Service Provider (CSP) to a Key Storage Provider (KSP)], inspired from Microsoft TechNet Article talking about the same topic. I will try to give you more information and more examples about this topic, and how this plays big role in your journey to phase out SHA-1 and start using SHA-2

Please read the following topics before continue reading this blog post:

I will not discuss why and when you should migrate from CSP to KSP. However,I will only talk about the steps needed to migrate. After the migration, you can then reconfigure the CA to issue certificates by using the SHA-2 hash algorithm rather than the less secure hash algorithm of SHA-1

Moving to a new blog

I am moving to a new blog format, please follow this link to continue reading 🙂


66 comments on “SHA-2 Support – Migrate your CA from CSP to KSP

  1. Pingback: What makes a CA capable of issuing certificates that uses SHA-2? | Ammar Hasayen - Blog

  2. Pingback: PKI Certificate Services SHA-1 Deprecation | Ammar Hasayen - Blog

  3. Pingback: SHA-1 Broken, Migrating to SHA-2 | Ammar Hasayen - Blog

  4. Pingback: Deploy Offline Root CA in Windows 2012 R2 – SHA-2 Ready | Ammar Hasayen - Blog

  5. I have an error at step 6, -exportPFX command failed: 0x8009000b (-2146893813 NTE_BAD_KEY_STATE). Key not valid for use in specified state. It appears that the private key is NOT exportable which I think is leading to this error, this is on a windows server 2012r2 VM, do you have any suggestions on how to get around this problem?

  6. Hi,

    I get an access denied error on step 6. Running the prompt as admin and also local admin on the machine. Any ideas?


  7. after running certutil -setreg ca\csp\CNGHashAlgorithm SHA256
    starting the certsvc
    Certutil –v –getreg ca\csp\HashAlgorithm
    I still get CALG_SHA1 shouldn’t this now read SHA2 ??

  8. After all steps attempting run CA service and get error:
    Keyset does not exist 0x80090016 (-2146893802 NTE_BAD_KEYSET)

  9. I’v tried this twice on a Windows 2008R2 CA. Each time I get a Keyset does not exist 0x80090016 when trying to restart the service at the end. Any ideas?

    • I faced troubles when working with Root CA running 2008 R2. What i did to solve this is to upgrade my root CA to 2012 R2 and then complete the steps. It takes no effort or knowledge to upgrade your root CA to 2012 R2 and no risk. I blogged about this recently.

  10. I tried this on SBS 2011. It did not work and had to reinstall a back up. Could someone help me out on how to do this on SBS 2011? I have searched the internet and this blog post seems to come closest, but not all the way …

    • I wish i can belp man. I dont have SBS to try this on. I just shared my experience in doing it in windows 2012. I agree that there is not enough documentation and i spent some time until it worked for me.

  11. My HashAlgorithm for my CA is 256, however, when I try to create a new CSR through certsrv, the hash algorithm options are still in SHA1 format. How do I get certsrv to show sha2 hash algorithm options?

    • So what we did is to something like this

      You have a dirty shirt, you remove it from your house (old CA), you then import it to a cleaner machine ( server that supports KSP), then you export the Shirt from the cleaner [ Now the key is KSP compatible] , and then you go to your house (your CA), and import it a gain but now it is clean:)

      • I think Alfonso (and I) are wondering why you’d backup the old key in SHA-1 format then restore that same backed up key (C:\RootCA.p12) in SHA-1 format to an updated KSP. Why wouldn’t we use C:\NewCert.p12 with that -restorekey vommand??

        In your Step 7, your command says “Certutil -restorekey C:\RootCA.P12”. Should it not be “Certutil -restorekey C:\NewCert.P12” instead?

  12. Good job, Ammar!

    Your manual was very usefull for me. I have succesffully migrated to SHA256 signing algorithm with OS upgrade up to Windows Server 2012 R2.

    I should note one thing about “Step 4: Delete the CA Private Key”. It seems to be not enough just remove current private key by its Cert Hash value in case you had changed CA keypair ever before. In such situation you have a chain of keys (and CA’s certificates) from older ones to current and certificates generated by your CA contain special extension named “Previous CA Certificate Hash” which refers to previous certificate. It is important to have all keypairs in chain installed in your CA’s keystore. And keystore should be of one type for all keypairs as I found. When you delete just a current key and then import the private key to KSP in Step 5, all other keys were not touched and remain in keystore as a Ms CSP keypiars cause they were already existing during import. This fact forms an issue at step 6, “Export the private key from KSP” so I couldn’t export all keys in chain nor by certutil command, nor via Certification Authority GUI.

    To workaround of this issue I had manually deleted old keys in CA’s chain from computer’s store via Certificates mmc applet (suppose it may be done by command line, but GUI is easier for me) just after step 4. Then all keys in chain were successfully restored in a KSP store during step 5, “Import the private key to KSP”. Step 6, “Export of the private key from KSP” works fine after that and created .p12 file contains all chained keys in KSP compatible format.

  13. Excellent post. Following this article I managed to migrate a Win2008 CA from SHA-1 to SHA-2. Old SHA-1 certificate were still trusted. Keep up the good work

  14. Pingback: My readings in 2015 week 45 | My path to become awesome dev

  15. HY!

    I have a Server 2012 R2 Standard (6.3.9600 N/A Build 9600) and some Problem with point “5 – Import the private key to KSP” and “6 – Export the private key from KSP”.

    I tried it in a Administrator PowerShell as well in a Administrator Command line.

    PS C:\> Certutil -csp “Microsoft Software Key Storage Provider” -importpfx “C:\CA_Migrate_SHA256\Backup_with_GUI\TUFDOM TEST ROOT11.p12”
    Enter PFX password:
    Certificate “TUFDOM TEST ROOT11” added to store.

    CertUtil: -importPFX command completed successfully.

    PS C:\> Certutil -exportpfx my “TUFDOM TEST ROOT11” C:\TEMP\TestExport.p12
    my “Personal”
    ================ Certificate 1 ================
    Serial Number: 3747ce1f7989769d4f27ad51d4d7b979
    Issuer: CN=TUFDOM TEST ROOT11, DC=tufdom, DC=local
    NotBefore: 16.07.2014 09:30
    NotAfter: 16.07.2019 09:40
    Subject: CN=TUFDOM TEST ROOT11, DC=tufdom, DC=local
    Certificate Template Name (Certificate Type): CA
    CA Version: V0.0
    Signature matches Public Key
    Root Certificate: Subject matches Issuer
    Template: CA, Root Certification Authority
    Cert Hash(sha1): 27 bf 25 cf 52 69 9c ca 39 fd d5 0b 10 b4 ff 01 87 d7 39 84
    Key Container = TUFDOM TEST ROOT11-039df928-13db-421e-897b-92548494fc4e
    Unique container name: 91bce7586107239cd4fbdb362a39205e_f4e7fd57-f9a9-4bfd-8a1f-101ab0f0df2d
    Provider = Microsoft Software Key Storage Provider
    Private key is NOT exportable
    Signature test passed
    Enter new password for output file C:\TEMP\TestExport.p12:
    Enter new password:
    Confirm new password:
    CertUtil: -exportPFX command FAILED: 0x8009000b (-2146893813 NTE_BAD_KEY_STATE)
    CertUtil: Key not valid for use in specified state.
    PS C:\>

    There is no chance to get this running properly.

    When I try to export the imported certificate with the MMC GUI there is also no possibility to “export with the private key”.

    When I try to import the shown P12 key with the MMC GUI I immediately get to possibility to mark it as “exportable”.

    certutil Version: 6.3.9600.17415


    I tried it on my Windows 10 and it was working very well!

    certutil Version 10.0.10240.16384


    Both machines have the latest Windows Updates installed.

    So I think there must be a problem with certutil on my windows 2012 R2 server.

    For further testing I tried to copy the W10 – certuil to my W2012R2 server and did it again.

    In commandline a get the following error:

    C:\CA_Migrate_SHA256\Certutil_W10>Certutil -exportpfx my “TUFDOM TEST ROOT11” C:\TEMP\TestExportx.p12
    my “Personal”
    (null) 3747ce1f7989769d4f27ad51d4d7b979
    CN=TUFDOM TEST ROOT11, DC=tufdom, DC=local
    16.07.2014 09:30
    16.07.2019 09:40
    CN=TUFDOM TEST ROOT11, DC=tufdom, DC=local
    Certificate Template Name (Certificate Type): CA
    CA Version: V0.0
    (null): CA, Root Certification Authority
    (null) 27 bf 25 cf 52 69 9c ca 39 fd d5 0b 10 b4 ff 01 87 d7 39 84
    (null): 91bce7586107239cd4fbdb362a39205e_f4e7fd57-f9a9-4bfd-8a1f-101ab0f0df2d
    CertUtil: Key not valid for use in specified state.


    The powershell result it the same like it was with the original certutil from W2012R2.

    Do you have any ideas?



  16. I’ve just been followng the MS guide to upgrade our CSP to KSP and have a problem. I stumbled on this guide, and it seems to have some useful into. We too were in a position of having an original Win2003 CA that was upgraded to 2008 (x86). I’ve migrated this all to 2012 R2 now, and it works ok, but the CSP is still the original one, and our signing hash is still SHA-1. So, now I’ve completed the O/S migration, I’m trying to upgrade the root CA and two subordinate CA’s to SHA-2 (root CA first).

    I’ve done all the backups, deleted the original keys and am trying to re-import the .p12 key using the following command;

    certutil -csp “Microsoft Software Key Storage Provider” -importpfx MY “C:\CABackup\.p12”

    After entering the password, I immediately get this error;

    CertUtil: -importPFX command FAILED: 0x80092007 (-2146885625 CRYPT_E_SELF_SIGNED)
    CertUtil: The specified certificate is self signed.

    Of course the cert is self-signed – it’s our root signing CA. No idea why this has happened. The cert is fine, and exported ok.

    Any ideas?

    • If you are like me and get stuck at Step 5/6 because of the NTE_BAD_KEY_STATE error, try the following syntax to import your file with the exportable option:

      Import-PfxCertificate -FilePath C:\backup\yourcert.p12 cert:\localMachine\my -Exportable

      As per “Sander Goudswaard’s” link above to the TechNet Article – this is the working syntax I used on Server 2012 R2 and it got me through. Use this instead of “certutil -csp ……” and then continue on.

  17. Thanks a lot, work perfectly for me on 2012 server. The clue was the RootCA private key that was in a CSP and after migration in KSP I am able to sign in SHA512.

  18. Hello again,
    following these instructions, is it possible to migrate a 2008R2 CA from CSP to KSP without migrating to 2012 Server? Is it possible to keep in running on 2008 R2 at the end?

  19. Hi.
    At Step 5 is error.

    Import-PfxCertificate -FilePath C:\backup\yourcert.p12 cert:\localMachine\my – Exportable – OK!

    At Step 6 is error.
    Certutil -exportpfx my “ROOT-CA” C:\backup\newrootca.p12
    The error : Private key is NOT plain text exportable

    $mypwd = ConvertTo-SecureString -String “1234” -Force –AsPlainText
    Get-ChildItem -Path cert:\LocalMachine\my | Export-PfxCertificate -FilePath C:\backup\newrootca.p12 -Password $mypwd
    It is OK!

    But, step 7 is error
    Certutil -restorekey C:\Certificates\newrootca.p12
    Enter PFX password:
    CertUtil: -restoreKey command FAILED: 0x8007000d (WIN32: 13)
    CertUtil: The data is invalid.

  20. Very good guide, it functions in Windows 2008 R2 and SBS 2011, BUT:
    – In step 7 you must use the “NewCert.p12” instead of the initial “RootCa.p12”:
    Certutil -restorekey C:\NewCert.P12

    – In Step 9 you should mark it better, that the RegPath ends with “EncryptionCSP” and not “CSP”

  21. For a clean implementation in SBS 2011 you have additionally Steps

    1. Add a new CA-Certificate (it will use SHA256 automatically) and Export it as sbscertificate.cer

    2. Renew the Webservercertificate via IIS-Manager. It will use SHA256 automatically

    3 Assign the new Webservercertificate via IIS-Manager to all Websites, that use https

    4 Activate Remote Desktop Gateway Manager:
    “dism /online /Enable-Feature:Gateway-UI”

    5 Assign the new Webservercertificate via Remote Desktop Gateway Manager

    6. Modify “Install Certificate” with the new Ca – Certificate sbscertificate.cer, exported in Step 1

    7 Install “Install Certificate” to all Clients, that connect remote to the SBS

    • I tired all the steps twice and both times on my SBS2011. I was unable to start certsvc Key does not exist. 0x8009000d (-2146893811). I ended up having to restore everything back. Did it work for you? Any modifications?

      • FWIW on a SBS 2011 I had same problem, restored everything then redo it but removing the private keys of old certificates with an export through mmc + checking ‘remove key’ in the UI, then removing the old certificates by simply deleting them in mmc, and finally importing the first new certificate with certutil and the second with mmc (else there is an error duplicate certificate), then followed the article -> success.

  22. Fix for part 6 (Failed 0x80090000b). Run after part 5

    In PowerShell:
    Import-PfxCertificate –FilePath “XXX-InternalCA” cert:\localMachine\my -exportable -password (Read-Host -Prompt “Enter Password” -AsSecureString)

  23. I go through all the steps fine with no errors, but when I try to start the service back up after changing to SHA256, I get:

    keyset does not exist 0x80090016 (-2146893802 NTE_BAD_KEYSET)

    I checked my local store and all of the CA certs there have private keys associated with them so I’m not sure what’s going on. Any clue as to what may be going on? I’m on Server 2012R2. Just migrating from Microsoft Strong Cryptographic Service Provider to Microsoft Software Key Storage Provider. Any help is greatly appreciated. Thanks for the article!

  24. The step 10 ( certutil -setreg ca\csp\CNGHashAlgorithm SHA256
    ) is the last instruction to perform from SHA1 to SHA2. Should I also continue to renew CA server certificate to SHA256 ? Please advise

    • Reissuing the root is optional. all new certificates generated will be SHA2, but if you want your root to be SHA256 then yes you will need to do that. As far as MSFT/Googles security stance I think as long as the root is still SHA1 there is no problems but the downstream certificates generated need to be SHA2.

      That being said It was a good time for us to go ahead and bump up the Key length and for our internal PKI.

  25. Pingback: Active Directory Certificate Authority Sha1 to Sha2 Migration 實錄 – ROL801 WordPress

  26. After completing this successfully now when I attempt to backup the CA I get the dreaded Windows cannot backup one or more private keys because the CSP does not support key export

  27. After all steps I’ve got the following error, when I attempting to run CA:
    “Invalid key 0x80090003 (-2146893821).”

    In the event log I could find the following event (translated from german language):
    “The Active Directory certificate services were not started: The current certification authority certificate could not be loaded or verified. invalid key 0x80090003 (-2146893821).”

    Any idea how can I fix this?

    Thanks a lot

    • I found the issue!
      At step 7 (Certutil –restorekey ) only non-expired certificates will be imported.
      At HKLM\system\CurrentControlSet\Services\Certsvc\Configuration\CA Common Name you will find the value CACertHash. This value is a history of all CA certs.
      Replace the expired certificates with “-“.

  28. I followed the instruction for server 2008R2 and all worked fine. But now I’m not able to export the private key.
    The associated private key has been marked as “non-exportable”.
    Any idea how to fix this?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s