X509AsymmetricSecurityKey.GetAsymmetricAlgorithm returns null after .Net 4.7.2 upgrade

依然范特西╮ 提交于 2019-12-11 15:01:16

问题


I have a problem with X509AsymmetricSecurityKey.GetAsymmetricAlgorithm running in a standard unit test. The test has been passing for years running on .Net Framework version 4.5.2 (C#), however since upgrading the project to version 4.7.2 it has ben failing as GetAsymmetricAlgorithm returns null. The exact same code runs perfect outside the test.

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;

Same code, same certificate, running though test GetAsymmetricAlgorithm returns null, running on "live" code (class library called from WebAPI) it works perfect.

Any ideas why? I can't see anything in the docs for previous .Net version changes, nothing in the Microsoft docs.

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

Thanks for any help on this.


回答1:


As Crypt32 suggested in a comment, the problem is that after you upgraded from targeting <= 4.6.2 to targeting 4.7(+) you got a "retargeting change" which says that GetAsymmetricAlgorithm is allowed to return instances of RSACng, which is the better RSA class in .NET Framework.

The best action in your code is to change the line to

RSA rsa = securityKey.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true) as RSA;

Then find the places that the code no longer compiles, and change from the RSACryptoServiceProvider variant method to the new RSA (base class) methods. (e.g. SignData(byte[], object) => SignData(byte[], RSASignaturePadding)).

You really want to avoid saying RSACng or RSACryptoServiceProvider if you can help it, since there are theoretical cases where RSACng won't work, and RSACryptoServiceProvider will be returned instead (older smartcards / HSMs which have a CAPI driver, but not a CNG driver).

This particular retargeting change is the System.IdentityModel version of https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/retargeting/4.5-4.7.2#wcf-transport-security-supports-certificates-stored-using-cng, which seems to have not been written down. If you need to turn this off, the setting name is Switch.System.IdentityModel.DisableCngCertificates.



来源:https://stackoverflow.com/questions/53535972/x509asymmetricsecuritykey-getasymmetricalgorithm-returns-null-after-net-4-7-2-u

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!