使用 .NET Core 5 签署数据,我收到错误 "Error occurred during a cryptographic operation."

Signing data with .NET Core 5, I get the error "Error occurred during a cryptographic operation."

尝试使用带证书的 CMS 通过 .NET Core 对数据签名时出现错误

X509Store st = new X509Store(StoreName.My, StoreLocation.LocalMachine);
st.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certSelected = st.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
st.Close();

var signerCert = certSelected[0];

ContentInfo contentInfo = new ContentInfo(msg);
SignedCms signedCms = new SignedCms(contentInfo, true);
CmsSigner cmsSigner = new CmsSigner(signerCert);
cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;
signedCms.ComputeSignature(cmsSigner, false);

计算签名时出现以下错误

Error occurred during a cryptographic operation.
   at Internal.Cryptography.Pal.Windows.HelpersWindows.GetProvParameters(SafeProvOrNCryptKeyHandle handle)
   at Internal.Cryptography.Pal.Windows.PkcsPalWindows.GetPrivateKey[T](X509Certificate2 certificate, Boolean silent, Boolean preferNCrypt)
   at Internal.Cryptography.Pal.Windows.PkcsPalWindows.GetPrivateKeyForSigning[T](X509Certificate2 certificate, Boolean silent)
   at System.Security.Cryptography.Pkcs.CmsSignature.RSAPkcs1CmsSignature.Sign(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, String& signatureAlgorithm, Byte[]& signatureValue)
   at System.Security.Cryptography.Pkcs.CmsSignature.Sign(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, String& oid, ReadOnlyMemory`1& signatureValue)
   at System.Security.Cryptography.Pkcs.CmsSigner.Sign(ReadOnlyMemory`1 data, String contentTypeOid, Boolean silent, X509Certificate2Collection& chainCerts)
   at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent)

相同的代码适用于 .NET Framework 4.5.2

知道这里可能有什么问题以及如何在 .NET Core 中修复它吗?

我通过以下方式成功实现了:​​

  • 在 ContentInfo 中定义 Oid
  • 在 CmsSigner 中定义 Oid
  • 为 CmsSigner 使用不同的构造函数

下面的新代码进行了更改

X509Store st = new X509Store(StoreName.My, StoreLocation.LocalMachine);
st.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certSelected = st.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
st.Close();

var signerCert = certSelected[0];

Oid dstOid = new Oid("1.2.840.113549.1.7.2"); // PKCS#7
ContentInfo contentInfo = new ContentInfo(dstOid, msg);
SignedCms signedCms = new SignedCms(contentInfo, true);

CmsSigner signerWindowStore = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signerCert, signerCert.GetRSAPrivateKey());
signerWindowStore.DigestAlgorithm = new Oid("1.3.14.3.2.26"); // SHA1
signerWindowStore.IncludeOption = X509IncludeOption.EndCertOnly;
signedCms.ComputeSignature(signerWindowStore, false);