X509AsymmetricSecurityKey.GetAsymmetricAlgorithm returns .Net 4.7.2 升级后为空

X509AsymmetricSecurityKey.GetAsymmetricAlgorithm returns null after .Net 4.7.2 upgrade

我在标准单元测试中遇到 X509AsymmetricSecurityKey.GetAsymmetricAlgorithm 运行 问题。该测试已经在 .Net Framework 4.5.2 (C#) 版上通过多年 运行,但是自从将项目升级到 4.7.2 版后,它一直失败,因为 GetAsymmetricAlgorithm returns 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 returns null,运行 "live" 代码(class 从 WebAPI 调用的库)它工作完美。

知道为什么吗?我在以前的 .Net 版本更改的文档中看不到任何内容,在 Microsoft 文档中也看不到任何内容。

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

感谢您对此的任何帮助。

正如 Crypt32 在评论中建议的那样,问题是在您从目标 <= 4.6.2 升级到目标 4.7(+) 后,您得到一个“retargeting change”,它表示 GetAsymmetricAlgorithm 被允许 return RSACng 实例,这是 .NET Framework 中更好的 RSA class。

代码中的最佳操作是将行更改为

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

然后找到代码不再编译的地方,将RSACryptoServiceProvider变体方法更改为新的RSA(基础class)方法。 (例如 SignData(byte[], object) => SignData(byte[], RSASignaturePadding))。

如果可以的话,你真的想避免说 RSACngRSACryptoServiceProvider,因为理论上存在 RSACng 不起作用的情况,而 RSACryptoServiceProvider将被 returned 替代(具有 CAPI 驱动程序但没有 CNG 驱动程序的旧智能卡/HSM)。

这个特定的重定向更改是 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.