mimekit - 无法使用智能卡上的私钥创建 CmsSigner
问题描述
当我尝试创建 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)
谢谢。
解决方案
您使用的是哪个版本的 .NET?
检查MimeKit.Cryptography.WIndowsSecureMimeContext
您是否可以使用(只要您net45
在 packages.config 中引用 MimeKit 的目标,它就应该适用于 >= .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;
}
}
}
}
}
}
推荐阅读
- python - Python Selenium Edgedriver 卡在地址栏中显示“数据;”,而不是打开网页
- facebook - Facebook 群组页面上的 Google 表格 importxml
- reactjs - 反应,有条件的 setState 只需点击一个按钮
- .htaccess - mod_rewrite 对参数名称的限制 - 字母 m
- webpack - 在生产构建后使用 webpack 在 next.js 中创建单独的 CSS 文件
- python - 将特定文本放入 pandas 数据框中,使用 BeautifulSoup 进行网络抓取
- c# - Ef Core 一对多与连接表
- javascript - javascript 中的三元条件未选择按钮单选
- android-viewpager2 - 与 viewpager2 和异步 diffutilities 一起使用时,Recyclerview 未显示正确的值
- shell - 通过 shell 命令在 Make 中分配宏值