Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Programmatically Delete X.509 SSL Cetificates.

5.00/5 (3 votes)
23 Feb 2011CPOL 23.8K  
The solution in this tip will enable you to delete SSL certificates programmatically when you receive the error InvalidOperationException: Found multiple X.509 certificates.
This post is my modified version of two solutions posted on the .NET Framework Developer Forum at: InvalidOperationException: Found multiple X.509 certificates and Getting System.Security.Cryptography.CryptographicException: Access is denied. error on store.Open(OpenFlags.ReadWrite). The credit goes to Madhu Ponduru - MSFT and terryc_ms.

The two posts referred to above helped me to solve an issue that I was having on a computer that had multiple SSL certificates with the name localhost, the location localmachine, and the store trustedpeople. Altogether, there were four certificates. This solution deleted the four offending SSL certificates, and allowed me to create a new one for development purposes.

NOTE: BEFORE PROCEEDING, BE VERY CAREFUL THAT YOU DO NOT DELETE THE WRONG CERTIFICATE.

The code below is a simple C# console application. The three properties that you will need to change to suite your situation are Name, Location, and Store.

MSIL
/*************************************************************************
 * Delete multiple X.509 SSL Certificates.
 ************************************************************************/

using System;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.IO;
using System.Security.Cryptography.X509Certificates;

namespace SslIssuesDebugger
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                X509Store store = new X509Store(
                    StoreName.TrustedPeople, StoreLocation.LocalMachine
                );
                StorePermission sp = 
                    new StorePermission(PermissionState.Unrestricted);
                sp.Flags = StorePermissionFlags.OpenStore;
                sp.Assert();
                store.Open(OpenFlags.ReadWrite | OpenFlags.MaxAllowed);
                X509Certificate2Collection collection =
                    (X509Certificate2Collection)store.Certificates;
                X509Certificate2Collection fcollection =
                    (X509Certificate2Collection)collection.Find(
                        X509FindType.FindBySubjectName, 
                        "localhost", false
                    );
                Console.WriteLine(
                    "Number of certificates: {0}{1}",   
                    fcollection.Count, Environment.NewLine
                );
                foreach (X509Certificate2 x509 in fcollection)
                {
                    byte[] rawdata = x509.RawData;
                    Console.WriteLine(
                        "Friendly Name: {0}{1}", 
                        x509.FriendlyName, Environment.NewLine
                    );
                    Console.WriteLine(
                        "Simple Name: {0}{1}", 
                        x509.GetNameInfo(X509NameType.SimpleName, true), 
                        Environment.NewLine
                    );
                    store.Remove(x509);
                    Console.WriteLine(
                        "X509Certificate2 for localhost 
                        removed."
                    );
                }
                store.Close();
            }
            catch (CryptographicException ex)
            {
                Console.WriteLine(ex);
            }
        }
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)