无法使用智能卡上的私钥创建 CmsSigner
Unable to create CmsSigner with private key on smart card
当我尝试创建 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
(只要您在 [=23= 中引用 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;
}
}
}
}
}
}
当我尝试创建 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
(只要您在 [=23= 中引用 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;
}
}
}
}
}
}