.Net 4.6.2 上的 RSACryptoServiceProvider "Key does not exist"

RSACryptoServiceProvider "Key does not exist" on .Net 4.6.2

我正在使用 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/ 他们提到更改证书和签名代码,但我不确定到底是什么损坏了。

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

创建 RSACryptoServiceProvider 的实例时,您需要指定具有指定 KeyContainerName 的 CspParameters 对象:

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