2012-02-17 34 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); 
      } 
     } 
    } 
}