Hi,
I am trying to exercise the methods and properties of X509Certificate2 class as I wish to convert an application from .Net Framework 1.1 with its many P/Invoke and CAPICOM calls to a pure .Net app using .Net 2.0 improved certificate/crypto support.
I am playing with the MSDN C# sample app for X509Certificate2.PrivateKey Property with one small modification (suggested improvement )
Any thoughts why I get an exception
"System.Security.Cryptography.CryptographicException: Keyset does not exist"
on the line
Console
.WriteLine("Private Key: {0}{1}", x509.PrivateKey.ToXmlString(false), Environment.NewLine);if I select a certificate that has an AT_EXCHANGE key associated.
If I select a certificate that has an AT_SIGNATURE key associated, then the code appears to run correctly and not throw an exception!
Note that the if (x509.HasPrivateKey) is true which confirms that the selected certificate has a private key.
Also note that using .Net 1.1 and P/Invoke calls I can find the container name and then create a RSACryptoServiceProvider() object to use the private key of a cert associated with an exchange key.
Any suggestions would be appreciated.
Richard
using System;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.IO;
using System.Security.Cryptography.X509Certificates;
class CertSelect
{
staticvoid Main()
{
try
{
X509Store store = new X509Store("MY",StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid,DateTime.Now,false);
X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Test Certificate Select","Select a certificate from the following list to get information on that certificate",X509SelectionFlag.MultiSelection);
Console.WriteLine("Number of certificates: {0}{1}",scollection.Count,Environment.NewLine);
foreach (X509Certificate2 x509 in scollection)
{
byte[] rawdata = x509.RawData;
Console.WriteLine("Content Type: {0}{1}",X509Certificate2.GetCertContentType(rawdata),Environment.NewLine);
Console.WriteLine("Friendly Name: {0}{1}",x509.FriendlyName,Environment.NewLine);
Console.WriteLine("Certificate Verified?: {0}{1}",x509.Verify(),Environment.NewLine);
Console.WriteLine("Simple Name: {0}{1}",x509.GetNameInfo(X509NameType.SimpleName,true),Environment.NewLine);
Console.WriteLine("Signature Algorithm: {0}{1}",x509.SignatureAlgorithm.FriendlyName,Environment.NewLine);
if
(x509.HasPrivateKey){
Console.WriteLine("Private Key: {0}{1}",x509.PrivateKey.ToXmlString(false),Environment.NewLine);
}
Console.WriteLine("Public Key: {0}{1}",x509.PublicKey.Key.ToXmlString(false),Environment.NewLine);
Console.WriteLine("Certificate Archived?: {0}{1}",x509.Archived,Environment.NewLine);
Console.WriteLine("Length of Raw Data: {0}{1}",x509.RawData.Length,Environment.NewLine);
X509Certificate2UI.DisplayCertificate(x509);
x509.Reset();
}
store.Close();
}
catch (CryptographicException)
{
Console.WriteLine("Information could not be written out forthis certificate.");
}
}
}