NET 4.7.2升级后X509AsymmetricSecurityKey.GetAsymmetricAlgorithm返回null

时间:2018-11-29 09:42:49

标签: x509certificate

我在标准单元测试中运行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文档中什么也看不到。

https://docs.microsoft.com/en-us/dotnet/api/system.identitymodel.tokens.x509asymmetricsecuritykey.getasymmetricalgorithm?view=netframework-4.7.2

谢谢您的帮助。

1 个答案:

答案 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))。

您真的想避免说出RSACngRSACryptoServiceProvider,因为在理论上情况下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