The information in this article is intended for software developers.  


using System;
using System.Security.Cryptography.X509Certificates;
using System.Web;
using System.Net;
using System.IO;
using System.Security.Cryptography;
namespace certtest
{
    class Program
    {
        static void Main(string[] args)
        {

            //Select certificate location--note this tools always uses the "Personal" cert store in whatever
            //location you choose
            
            //local machine store
            StoreLocation certstore = StoreLocation.LocalMachine;
            //current user store
            //certstore = StoreLocation.CurrentUser;
            
            //set true/false below for types of keys you want to test
            bool testLegacy = true; //false;
            bool testCNG = true; //false;
            
            //Enter serial numbers for legacy and/or CNG keys here
            //Don't enter spaces show in cert manager properties
            string legacyserial = "40e9";  //Legacy key
            string cngserial = "5ab1";  //CNG key

            if (testLegacy)
            {
                Console.WriteLine(TestLegacy(legacyserial, certstore));
            }
            if (testCNG)
            {
                Console.WriteLine(TestCNG(cngserial, certstore));
            }
        }

        static string TestLegacy(string serial, StoreLocation certstore)
        {
            X509Certificate cert = null;
            X509Store store = new X509Store(StoreName.My, certstore);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindBySerialNumber,
                                       serial, true);
            if (col.Count == 0)
            {
                return "could not find legacy cert with serial number " + serial;
            }

            try
            {
                cert = col[0];
                X509Certificate2 samecert = (X509Certificate2)cert;
                if (samecert.HasPrivateKey)
                {
                    AsymmetricAlgorithm key = samecert.PrivateKey;
                }
                else
                {
                    return "Cert has no private key!";
                }
            }
            catch (CryptographicException)
            {
                return "Private key exists, but we don't have permission to read it.";
            }
            
            string currentUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            return "This cert has a private key and this user, " + currentUser + ", was able to access it.";

        }
        static string TestCNG(string serial, StoreLocation certstore)
        {
            /*
             Note this method tests CNG cert private keys by trying to open a remote connection authenticating using the cert.  
             .NET doesn't handle CNG keys very well and this is the easiest way to test it
             */
            X509Certificate cert = null;
            X509Store store = new X509Store(StoreName.My, certstore);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindBySerialNumber,
                                   serial, true);
              if (col.Count == 0)
            {
                return "could not find legacy cert with serial number " + serial;
            }
            try
            {
                cert = col[0];
                //Don't use the debugger to try to inspect the PrivateKey property on the samecert object. 
                //It will throw an exception even if you have permission.  .NET limitation.  
                X509Certificate2 samecert = (X509Certificate2)cert;
                if (samecert.HasPrivateKey)
                {
                    //rsaobj = samecert.GetRSAPrivateKey();
                    string uri = "https://iam-ws.u.washington.edu:7443/group_sws/v2/group/u_nebula_gca";
                    HttpWebRequest _request = (HttpWebRequest)HttpWebRequest.Create(uri);
                    _request.AllowAutoRedirect = true;
                    _request.Method = "GET";
                    _request.ClientCertificates.Add(cert);
                    WebResponse webResponse = null;
                    HttpWebResponse _response = null;
                    try
                    {
                        webResponse = _request.GetResponse();
                        _response = (HttpWebResponse)webResponse;
                    }
                    catch (WebException ex)
                    {
                        if (ex.Message == "The request was aborted: Could not create SSL/TLS secure channel.")
                        {
                            return "Private key exists, but we don't have permission to read it.";
                        }
                        else
                        {
                            return "something went wrong with this SSL client authentication attempt, but " +
                                "we're not sure what.  The error from this code was " + ex.Message +
                                 " and the error (if any) from the remote server was " + ex.Response;
                        }
                    }
                }
                else
                {
                    return "Cert has no private key!";
                }
            }
            catch (CryptographicException ex)
            {
                return "Unknown crypto error: " + ex.Message;
            }
           
            string currentUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            return "This cert has a private key and this user, " + currentUser + ", was able to access it.";

        }
    }
}