2012-02-17 10 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

모든 스마트 카드 인증서에는 다른 인증서에는없는 두 가지 속성이 있습니다. 그들은 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); 
      } 
     } 
    } 
}     
관련 문제