加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 为什么SignedCms.ComputeSignature()方法抛出“Provider的

发布时间:2020-12-16 01:41:57 所属栏目:百科 来源:网络整理
导读:这可能看起来像一个简单的问题,但它真的让我摸不着头脑.麻烦的是我们的代码在.NET framework 3.5上运行时运行良好,但现在我们已经切换到.NET 4.0,我们遇到了这个错误.这是相关的代码: SignedCms signed = new SignedCms(content,false);CmsSigner signer =
这可能看起来像一个简单的问题,但它真的让我摸不着头脑.麻烦的是我们的代码在.NET framework 3.5上运行时运行良好,但现在我们已经切换到.NET 4.0,我们遇到了这个错误.这是相关的代码:

SignedCms signed = new SignedCms(content,false);
CmsSigner signer = new CmsSigner(
    SubjectIdentifierType.IssuerAndSerialNumber,signingCertificate);

signed.ComputeSignature(signer);

再一次,在.NET 3.5上,这很好用.但是现在我们的项目以.NET 4.0为目标,它在使用完全相同的证书时会抛出CryptographicException.

[CryptographicException: Provider's public key is invalid.]
   at System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo(CmsSigner signer,Boolean silent)
   at System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner signer,Boolean silent)
   at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer,Boolean silent)
   at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer)
   ...

有什么想法会导致这种情况吗?

UPDATE

深入挖掘后,我发现问题只发生在我自己反序列化签名证书时.如果我从机器商店加载它,一切正常.所以,很明显,我的反序列化代码有问题.此代码未更改.唯一的区别是它现在以.NET 4为目标.这是代码:

var result = new X509Certificate2(certificate);

byte[] decryptedKey;

// Long ugly code to decrypt private key omitted...                

var rsa = new RSACryptoServiceProvider(new CspParameters
{
    Flags = CspProviderFlags.UseMachineKeyStore
});

try
{
    rsa.ImportCspBlob(decryptedKey);

    result.PrivateKey = rsa;

    return result;
}
catch
{
    rsa.Dispose();
    throw;
}

解决方法

事实证明,问题是RSACryptoServiceProvider中的一个微妙的,突破性的变化.在.NET 4.0之前,此类的新实例将具有随机生成的密钥容器名称(格式为“CLR {GUID}”).在.NET 4.0中,它将密钥容器名称保留为null. (或者它可能将它设置为null,因为这是我通过CspParameters传递的内容.)

在任何情况下,这意味着每个后续RSACryptoService提供程序都会覆盖任何先前提供程序的密钥对.当我的代码最终得到签名时,与证书关联的密钥对已被不同证书的密钥对覆盖. (因此“公钥无效”错误.)

解决方案是自己简单地生成一个随机名称.对我的反序列化代码的更改如下:

var rsa = new RSACryptoServiceProvider(new CspParameters
{
    Flags = CspProviderFlags.UseMachineKeyStore,KeyContainerName = String.Format("MyPrefix {{{0}}}",Guid.NewGuid())
});

try {
    rsa.PersistKeyInCsp = false; // ensure key is deleted when provider is disposed

    rsa.ImportCspBlob(decryptedKey);

    result.PrivateKey = rsa;

    return result;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读