【问题标题】:Find out whether a private key is on a hardware device without the device present查明私钥是否在没有设备存在的硬件设备上
【发布时间】:2012-02-17 16:04:45
【问题描述】:

我想知道证书的私钥是否存储在硬件设备中。
让我们假设以下应用程序

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(如果当时不存在智能卡),我就会提示插入设备。
有没有办法在不弹出这个烦人的“请插入智能卡”对话框的情况下获取相同的信息?

【问题讨论】:

    标签: .net smartcard


    【解决方案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);
                }
            }
        }
    }                 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 2010-09-12
      • 2019-06-19
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多