2012-02-17 60 views
2

我想知道证书的私钥是否存储在硬件设备中。
假设下面的应用找出没有设备的硬件设备上是否有私钥

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      X509Store store = new X509Store("MY", StoreLocation.CurrentUser); 
      store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); 

      foreach (X509Certificate2 x509 in store.Certificates) 
      { 
       if (x509.HasPrivateKey) 
       { 
        AsymmetricAlgorithm a = x509.PrivateKey; 
        RSACryptoServiceProvider r = a as RSACryptoServiceProvider; 
        if (null != r) 
        { 
         System.Console.WriteLine("hardware: " + r.CspKeyContainerInfo.HardwareDevice); 
         System.Console.WriteLine("Subject: " + x509.Subject); 
         System.Console.WriteLine("container: " + r.CspKeyContainerInfo.KeyContainerName); 
         System.Console.WriteLine("---"); 
        } 
       } 
      } 
     } 
     catch (CryptographicException ex) 
     { 
      Console.WriteLine("Information could not be written out for this certificate."); 
     } 
    } 
} 

我正在寻找的信息是r.CspKeyContainerInfo.HardwareDevice
但不幸的是,对于由基本智能卡csp提供的商店,一旦执行AsymmetricAlgorithm a = x509.PrivateKey(如果smardcard当时不存在),系统会提示我插入设备。
有没有办法获得相同的信息没有这个烦人的“请插入智能卡”对话框弹出?

回答

1

我注意到,我所有的智能卡证书都有其他证书没有的两个属性。他们可以通过CertGetCertificateContextPropertyCERT_SCARD_PIN_ID_PROP_IDCERT_SCARD_INFO_PROP_ID查询。我不知道这是否是确定的,但它对我有用。

这个例子应该只列出智能卡证书:

class Program 
{ 
    [System.Runtime.InteropServices.DllImport("crypt32.dll", SetLastError = true)] 
    extern public static bool CertGetCertificateContextProperty(IntPtr pCertContext, Int32 dwPropId, IntPtr pvData, ref Int32 pcbData); 

    const int CERT_SCARD_PIN_ID_PROP_ID = 90; 
    const int CERT_SCARD_INFO_PROP_ID = 91; 

    static bool CertificateHasProperty(X509Certificate x509, int propId) 
    { 
     int cbData = 0; 
     // If the property exists CertGetCertificateContextProperty returns true 
     // and sets cbData to the size of buffer required to hold the data. 
     return CertGetCertificateContextProperty(x509.Handle, propId, IntPtr.Zero, ref cbData); 
    } 

    static void Main(string[] args) 
    { 
     X509Store store = new X509Store("MY", StoreLocation.CurrentUser); 
     store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); 

     foreach (X509Certificate2 x509 in store.Certificates) 
     { 
      if (CertificateHasProperty(x509, CERT_SCARD_INFO_PROP_ID)) 
      { 
       Console.WriteLine("Subject: " + x509.Subject); 
      } 
     } 
    } 
}