这可能看起来像一个简单的问题,但它真的让我摸不着头脑.麻烦的是我们的代码在.NET framework 3.5上运行时运行良好,但现在我们已经切换到.NET 4.0,我们遇到了这个错误.这是相关的代码:
SignedCms signed = new SignedCms(content, false);
CmsSigner signer = new CmsSigner(
SubjectIdentifierType.IssuerAndSerialNumber,
signingCertificate);
signed.ComputeSignature(signer);
Run Code Online (Sandbox Code Playgroud)
再一次,在.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)
...
Run Code Online (Sandbox Code Playgroud)
有什么想法会导致这种情况吗?
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;
}
Run Code Online (Sandbox Code Playgroud)
事实证明,问题是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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6418 次 |
| 最近记录: |