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 文档中也看不到任何内容。
感谢您对此的任何帮助。
正如 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)
)。
如果可以的话,你真的想避免说 RSACng
或 RSACryptoServiceProvider
,因为理论上存在 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
.
我在标准单元测试中遇到 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 文档中也看不到任何内容。
感谢您对此的任何帮助。
正如 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)
)。
如果可以的话,你真的想避免说 RSACng
或 RSACryptoServiceProvider
,因为理论上存在 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
.