【问题标题】:Unable to create CmsSigner with private key on smart card无法使用智能卡上的私钥创建 CmsSigner
【发布时间】:2019-08-29 21:01:48
【问题描述】:

当我尝试创建 CmsSigner 来签署我的消息时遇到了错误。

基本上,我的个人证书存储中有多个证书具有相同的电子邮件地址(主题),当我使用 ApplicationPkcs7Mime.Sign() 方法时,它使用了错误的证书来签署我的消息。

因此,为了找到正确的证书,我基本上实现了搜索并初始化了正确的 CmsSigner 以用于签名。但是,我遇到了一个错误,我怀疑这是因为相应证书的私钥在我的智能卡内是不可导出的。这是我编写的代码和我得到的错误。

   X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly);
        X509Certificate2Collection collection = store.Certificates.Find(X509FindType.FindBySubjectName, userEmail, true);
        MimeKit.Cryptography.CmsSigner signer = null;

        foreach (X509Certificate2 cert in collection)
        {             
            if (cert.Issuer.Contains("My_Trusted_CA") && cert.HasPrivateKey)
            {

                foreach (X509Extension ext in cert.Extensions)
                {
                    if (ext.Oid.FriendlyName == "Key Usage")
                    {

                        X509KeyUsageExtension keyUsage = (X509KeyUsageExtension)ext;
                        System.Security.Cryptography.X509Certificates.X509KeyUsageFlags keyUsageFlags = keyUsage.KeyUsages;
                        if (keyUsageFlags.HasFlag(System.Security.Cryptography.X509Certificates.X509KeyUsageFlags.DigitalSignature))
                        {
                            Log("Certificate Found: " + cert.SerialNumber);
                            try
                            {
                                signer = new MimeKit.Cryptography.CmsSigner(cert);
                            } catch (Exception ex)
                            {
                                ThrowErrorMessage("Error creating CMS Signer: " + ex.Message + "\n" + ex.StackTrace);
                            }
                            break;
                        }
                    }
                }
            }
        }

这里是抛出的异常:

Error creating CMS Signer: Invalid type specified.
   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.Utils._ExportKey(SafeKeyHandle hKey, Int32 blobType, Object cspObject)
   at System.Security.Cryptography.RSACryptoServiceProvider.ExportParameters(Boolean includePrivateParameters)
   at MimeKit.Cryptography.AsymmetricAlgorithmExtensions.GetAsymmetricKeyParameters(RSACryptoServiceProvider rsa, Boolean publicOnly, AsymmetricKeyParameter& pub, AsymmetricKeyParameter& key)
   at MimeKit.Cryptography.AsymmetricAlgorithmExtensions.GetAsymmetricKeyParameter(RSACryptoServiceProvider rsa)
   at MimeKit.Cryptography.CmsSigner..ctor(X509Certificate2 certificate)

谢谢。

【问题讨论】:

    标签: mimekit


    【解决方案1】:

    您使用的是什么版本的 .NET?

    检查您是否可以使用 MimeKit.Cryptography.WIndowsSecureMimeContext(只要您在 packages.config 中引用 MimeKit 的 net45 目标,它就应该适用于 >= .NET v4.5)。

    假设您可以使用,我建议继承 WindowsSecureMimeContext 并覆盖 GetCmsSigner 方法。

    一旦你这样做了,你就可以或多或少地复制和粘贴你当前的逻辑,以获取正确的 CmsSigner,结果如下:

    protected override System.Security.Cryptography.Pkcs.CmsSigner GetCmsSigner (MailboxAddress mailbox, DigestAlgorithm digestAlgo)
    {
        var store = new X509Store (StoreName.My, StoreLocation.CurrentUser);
        store.Open (OpenFlags.ReadOnly);
    
        var collection = store.Certificates.Find (X509FindType.FindBySubjectName, userEmail, true);
        System.Security.Cryptography.Pkcs.CmsSigner signer = null;
    
        foreach (X509Certificate2 cert in collection)
        {             
            if (cert.Issuer.Contains("My_Trusted_CA") && cert.HasPrivateKey)
            {
                foreach (X509Extension ext in cert.Extensions)
                {
                    if (ext.Oid.FriendlyName == "Key Usage")
                    {
                        var keyUsage = (X509KeyUsageExtension)ext;
                        var keyUsageFlags = keyUsage.KeyUsages;
    
                        if (keyUsageFlags.HasFlag (System.Security.Cryptography.X509Certificates.X509KeyUsageFlags.DigitalSignature))
                        {
                            Log("Certificate Found: " + cert.SerialNumber);
                            try
                            {
                                signer = new System.Security.Cryptography.Pkcs.CmsSigner(cert);
                            } catch (Exception ex)
                            {
                                ThrowErrorMessage("Error creating CMS Signer: " + ex.Message + "\n" + ex.StackTrace);
                            }
                            break;
                        }
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-10-11
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多