.Net 4.6.2上的RSACryptoServiceProvider“密钥不存在”

时间:2016-11-30 17:27:16

标签: c# x509certificate2 rsacryptoserviceprovider

我正在使用PackageDigitalSignatureManager来签署Zip文件及其内容。 我的代码工作正常,直到我更新到.Net 4.6.2突然我得到了以下的经验:

System.Security.Cryptography.CryptographicException: Key does not exist 
bei System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
bei System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
bei System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash)
bei System.Security.Cryptography.RSAPKCS1SignatureFormatter.CreateSignature(Byte[] rgbHash)
bei System.Security.Cryptography.AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm hash)
bei System.Security.Cryptography.Xml.SignedXml.ComputeSignature()
bei MS.Internal.IO.Packaging.XmlDigitalSignatureProcessor.Sign(IEnumerable`1 parts, IEnumerable`1 relationshipSelectors, X509Certificate2 signer, String signatureId, Boolean embedCertificate, IEnumerable`1 signatureObjects, IEnumerable`1 objectReferences)
bei System.IO.Packaging.PackageDigitalSignatureManager.Sign(IEnumerable`1 parts, X509Certificate certificate, IEnumerable`1 relationshipSelectors, String signatureId, IEnumerable`1 signatureObjects, IEnumerable`1 objectReferences)
bei System.IO.Packaging.PackageDigitalSignatureManager.Sign(IEnumerable`1 parts, X509Certificate certificate, IEnumerable`1 relationshipSelectors, String signatureId)
bei System.IO.Packaging.PackageDigitalSignatureManager.Sign(IEnumerable`1 parts, X509Certificate certificate, IEnumerable`1 relationshipSelectors)

我使用的证书和私钥以及我使用的签名代码在过去几个月内根本没有变化。 唯一的变化是切换到.Net 4.6.2。

在找到这篇文章之前,我不确定发生了什么:https://blogs.msdn.microsoft.com/dotnet/2016/08/02/announcing-net-framework-4-6-2/ 他们提到更改证书和签名代码,但我不确定究竟是什么破坏了。

有谁知道如何解决这个问题? 有没有办法以向后兼容的方式运行我的应用程序?

1 个答案:

答案 0 :(得分:6)

创建RSACryptoServiceProvider实例时,需要使用指定的KeyContainerName指定CspParameters对象:

var cp = new CspParameters();
cp.KeyContainerName = "WhateverKeyContainerName";
var privateKey = new RSACryptoServiceProvider(cp);