Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clean my MachineKeys folder by removing multiple RSA files without touching IIS ones

I'm currently running IIS on my server using an app instantiating certificates.

By doing this code, for instance :

X509Certificate2 myX509Certificate = new 
X509Certificate2(Convert.FromBase64String(byteArrayRawCertificate), passwordCertificate, 
X509KeyStorageFlags.Exportable | 
X509KeyStorageFlags.MachineKeySet | 
X509KeyStorageFlags.PersistKeySet);

The code works fine. But I encounter a problem on my computer, on the following folder :

C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

3KB RSA files keep on being added on that folder. For now, I have more than a million files like those ones :

enter image description here

I would like to delete those files, but :

  • IIS uses one of them for encryption of password, or perhaps for other purposes and I don't know which one,
  • Deleting such a large folder can take time (like days)

    1. Is there a simple way not to create those files again and again ? (if I don't mention "MachineKeySet" while instanciating my certificate, this won't work)
    2. If not, is there a way to remove the created files without deleting IIS ones ?
    3. Is there a way to detect which files are used by IIS ?

Thanks in advance for your help.

like image 954
Thordax Avatar asked Dec 30 '15 10:12

Thordax


People also ask

What is the MachineKeys folder?

The MachineKeys folder stores certificate pair keys for both the computer and users. Both Certificate services and Internet Explorer use this folder.

What is Microsoft Crypto RSA MachineKeys?

This folder is used to store certificate pair keys for the system and its users. I wouldn't touch the files there as you could delete certificates used by Internet Explorer or other services, which would make them unusable after.

Where are machine keys stored?

A large number of files, ranging 50k or higher, are found in the operating system's Machine Keys folder (typically C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys).


2 Answers

There is some work for you. At first, you *MUST NOT* instantiate X509Certificate2 object from PFX file each time you need to access it. It is very BAD idea. This causes a new key file generated in the MachineKeys folder. Instead, you have to install the certificate to local certificate store once and then reference installed certificate.

Use X509Store.Add() method to install certficate to local store:

X509Certificate2 myX509Certificate = new 
X509Certificate2(Convert.FromBase64String(byteArrayRawCertificate), passwordCertificate, 
X509KeyStorageFlags.MachineKeySet);
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(myX509Certificate);
store.Close()

Next time you need to access your certificate and private key, use same X509Store class as follows:

X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 myCert = store.Certificates.Find(blablabla);
store.Close()

Instead of "blablabla", specify search filter: X509Certificate2Collection.Find(). You can use various filter options to locate your certificate. Most common used is by thumbprint.

Regarding large folder. If you are sure that there are no other certificates in the LocalMachine\My store, you can simply purge all contents and then install your certificate by using the code above.

like image 186
Crypt32 Avatar answered Sep 23 '22 07:09

Crypt32


Had the same problem, and was quite afraid to delete something, as I did read on other sources, that there are some system-critical files in there. By deleting those few you could end up with messed up IIS or other software.

As I had 8'000'000 of files there, I could not even open the folder - what I did was make small program in C# that delete files judging by OWNER - the user who created them! If they were created by IIS user, it would be safe to do this (please be sure you understand what you are doing!)

        var userNameToDeleteBy = "IIS_App_Pool_User_Goes_here!";

        var allFiles = (new DirectoryInfo(Directory.GetCurrentDirectory()).EnumerateFiles());

        var i = 0;

        foreach (var file in allFiles)
        {

            var fname = file.FullName;
            string user = System.IO.File
                .GetAccessControl(fname)
                .GetOwner(typeof(System.Security.Principal.NTAccount))
                .ToString();

            if(user.Contains(userNameToDeleteBy))
            {
                File.Delete(fname);
                i++;
            }

            //output only every 1k files, as this is the slowest operation
            if (i % 1000 == 0) Console.WriteLine("Deleted: " + i); 
        }

Also, if you really need to load cert from file, here is the answer on how to leave folder garbage-free:

Prevent file creation when X509Certificate2 is created?

like image 35
halloweenlv Avatar answered Sep 23 '22 07:09

halloweenlv