我在标准单元测试中运行X509AsymmetricSecurityKey.GetAsymmetricAlgorithm时遇到问题。该测试已经在.Net Framework 4.5.2版(C#)上运行了数年,但是自从将项目升级到4.7.2版以来,由于GetAsymmetricAlgorithm返回null,因此该测试以失败告终。完全相同的代码可以在测试之外完美运行。
X509Certificate2 cert = null;
var store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
// I'm actually using FindByThumbprint, just changing this here to protect keys
cert = store.Certificates[0];
// cert is valid X509, securityKey is valid
X509AsymmetricSecurityKey securityKey = new X509AsymmetricSecurityKey(cert);
// rsa is null
RSACryptoServiceProvider rsa = securityKey.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true) as RSACryptoServiceProvider;
相同的代码,相同的证书,尽管测试GetAsymmetricAlgorithm返回null,但仍在“实时”代码(从WebAPI调用的类库)上运行,因此运行良好。
任何想法为何?对于以前的.Net版本更改,我在文档中看不到任何内容,在Microsoft文档中什么也看不到。
谢谢您的帮助。
答案 0 :(得分:2)
正如Crypt32在评论中所建议的那样,问题是,从目标<= 4.6.2升级到目标4.7(+)后,您得到了一个“ retargeting change”,其中说允许GetAsymmetricAlgorithm返回以下实例: RSACng,它是.NET Framework中更好的RSA类。
代码中最好的操作是将行更改为
RSA rsa = securityKey.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true) as RSA;
然后找到代码不再编译的位置,并将其从RSACryptoServiceProvider变体方法更改为新的RSA(基类)方法。 (例如SignData(byte[], object)
=> SignData(byte[], RSASignaturePadding)
)。
您真的想避免说出RSACng
或RSACryptoServiceProvider
,因为在理论上情况下RSACng
无效,而RSACryptoServiceProvider
会有效而是返回(旧的智能卡/ HSM具有CAPI驱动程序,但没有CNG驱动程序)。
此特定的重定向目标更改是https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/retargeting/4.5-4.7.2#wcf-transport-security-supports-certificates-stored-using-cng的System.IdentityModel版本,似乎尚未记录下来。如果您需要关闭此设置,则设置名称为Switch.System.IdentityModel.DisableCngCertificates
。