We create a X509Certificate2 object in our ASP.NET app to make periodic outgoing connections. Every time one of these certificates is created a new file is created in:
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
That folder now has 4 million files that never get cleaned up. I've tried removing the Persist flag
new X509Certificate2(certBytes, p12Pwd, X509KeyStorageFlags.MachineKeySet);
//no X509KeyStorageFlags.PersistKeySet
but that doesn't help -- still get the 2Kb file on every call.
I got my hopes up when I saw this answer, but this is a 2008 R2 server, and the temp files are not 0 bytes, so it seems to be a different case.
How can we use a X509Certificate2 without filling up the disk?
If you create an X509Certificate certificate by specifying a PKCS7 signed file store for rawData, the X509Certificate is created for the certificate that signed the store rather than for any of the certificates within the store. Initializes a new instance of the X509Certificate2 class using a certificate file name. The name of a certificate file.
If you create an X509Certificate2 certificate by specifying a PKCS7 signed file store for rawData, the X509Certificate2 is created for the certificate that signed the store rather than for any of the certificates within the store. This API is not CLS-compliant.
The only value stored against this key is a blob containing the public portion of the X509 certificate: There's an MSDN article with more information about these paths if you need more details. As I mentioned, while in .NET you have an X509Certificate2 object containing both a private and public key, the "certificate" is only the public part.
You can get a copy of the current PCCERT_CONTEXT structure from the Handle property, but it is valid only during the lifetime of the X509Certificate2 object. Initializes a new instance of the X509Certificate2 class using information from a byte array. A byte array containing data from an X.509 certificate. An error with the certificate occurs.
Use .NET 4.6:
X509Certificate2 implements the IDisposable interface starting with the .NET Framework 4.6; in previous versions of the .NET Framework, the X509Certificate2 class does not implement this interface, and therefore the Dispose method does not exist.
I have the same issue on our server. The best way I found for now is to delete files from my code.
using System;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.IO;
using System.Security.Cryptography.X509Certificates;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Byte[] bytes = File.ReadAllBytes(@"D:\tmp\111111111111.p12");
X509Certificate2 x509 = new X509Certificate2(bytes, "qwerty", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
var privateKey = x509.PrivateKey as RSACryptoServiceProvider;
string uniqueKeyContainerName = privateKey.CspKeyContainerInfo.UniqueKeyContainerName;
x509.Reset();
File.Delete(string.Format(@"C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\{0}", uniqueKeyContainerName));
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With