2012-02-17 7 views
2

証明書の秘密キーがハードウェアデバイスに格納されているかどうかを調べたいと思います。
はのは、私が探している情報がr.CspKeyContainerInfo.HardwareDeviceにある次のアプリケーション秘密鍵が、デバイスが存在しないハードウェアデバイスにあるかどうかを確認します。

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."); 
     } 
    } 
} 

を想定してみましょう。
残念ながら、ベーススマートカードcspによって提供される店舗では、AsymmetricAlgorithm a = x509.PrivateKeyが実行されると(その時点でスマートカードが存在しない場合)、デバイスを挿入するように求められます。
この迷惑な「スマートカードを挿入してください」というダイアログが表示されない限り、同じ情報を取得する方法はありますか?

答えて

1

私のスマートカード証明書には、他の証明書にはない2つのプロパティがあることに気付きました。彼らはCertGetCertificateContextPropertyCERT_SCARD_PIN_ID_PROP_IDまたはCERT_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); 
      } 
     } 
    } 
}     
関連する問題