Secure Certificate Private Key in Windows – How to Guide

certificateiisnetSecuritywindows

I'm trying to secure a certificate's private key in Windows 10, but it looks like I'm misunderstanding what "Manage Private Keys" does.

This is the process I followed:

Edit – I tried repeating the full process this morning, and now I get an error as expected. See my answer below.


  1. fire up powershell (as an admin), create a self-signed cert and install it in the localmachine personal store:
New-SelfSignedCertificate -DnsName test.pfx -CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddDays(7)
  1. run certlm.msc

  2. find the test.pfx certificate, right-click it and choose all tasks > manage private keys

  3. remove everyone from the list, including administrators, so you get the message: "No groups or users have permission to access this object. However, the owner of this object can assign permissions." and click Ok.

  4. double click the certificate, go to the details tab, select 'properties only' from the dropdown, click the thumbprint, and copy and paste the thumbprint into notepad

  5. open up visual studio (as a normal user, not an admin, i.e. a different account) and create a new console application, and enter the following code:

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            const string thumbprint = "<THUMBPRINT>";

            using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
            {
                store.Open(OpenFlags.ReadOnly);

                var certs = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);

                if (certs.Count != 1)
                    throw new Exception("certificate count <> 1");
                var cert = certs[0];

                // why doesn't this fail? 
                var privateKey = cert.GetRSAPrivateKey();

                privateKey.Dispose();
            }
        }
    }
}
  1. copy/paste the thumbprint from notepad to replace in the code

  2. fire up the code


I'm expecting GetRSAPrivateKey() to fail, but it doesn't. (I can also use the private key to decrypt stuff if I add more code).

I also looked at %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\Keys and the permissions for the most recently modified private key "file" are as expected (i.e. no access for anyone).

Best Answer

I tried repeating the full process this morning, and now I get an error as expected. However, if I use yesterday's certificate thumbprint I still get no error despite them being setup exactly the same in certlm.msc

I subsequently realised (my bad!) that in the case of the previous certificate I had forgotten that I had imported it twice while testing, i.e. created + imported with powershell command as above, allowed read for a user, but then deleted and re-imported the pfx file.

I've thus discovered that when you delete the certificate file from certlm.msc it does NOT delete the related key file in %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\Keys, and if a user has e.g. read permissions on the previous key file, then the user still have access to the certificate. Equally updating permissions in certlm.msc has no effect on the previous file. Further, changing permissions on the old key file will affect permissions on the certificate. So presumably the effective permissions combine all existing permissions from all related key files, but I haven't dug into that confirm.

The takeaway is that certlm.msc shows the currently associated key file permissions not the key permissions (which are built up from all key files with the same key).

So the solution is to delete the previous related key file from %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\Keys.

I've raised it with MS in case they can provide more info: https://social.technet.microsoft.com/Forums/en-US/27e7780e-c755-41bc-9d9f-f141ba842733/certlmmsc-private-key-permissions-are-misleading-and-could-lead-to-a-security-breach?forum=winserversecurity