升级到 .NET Framework 4.8 后重新创建证书

Certificate recreation after upgrading to .NET Framework 4.8

我已将我们的一个 Web 应用程序从 .NET Framework 4.6 升级到 4.8。在代码深处的某个地方,一个 XML 字符串被签名,这个签名的 XML 被发送回客户端,客户端将验证签名。 XML 签名使用 SignedXml class.

由于其遗留性质,SHA1 仍在使用(请耐心等待!)。为了在升级 .NET Framework 时不破坏此行为,我必须在实际签署 XML:

之前设置以下 AppContext 开关
AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);

这解决了我本地机器上的所有问题,我可以成功签署 XMLs。

现在,在向前推进并将新代码版本部署到我们的暂存环境时,出现了一个新问题:XML 签名失败并出现 Invalid algorithm specified 异常。这是堆栈跟踪:

at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature)
at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)
at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash)
at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()

现在我偶然发现了 this question and especially that particular answer
所以我使用 certutil 检查了 CSP,我得到了以下结果:

问题:是否有机会减轻这种行为,例如。 G。通过使用另一段代码来签署 XML?还是我必须重新创建证书?

提前致谢!

最后我找到了适合我的解决方案。主要有两点:

1。 将 CSP 添加到现有证书

SwissSign 为我们的暂存环境(pemkey 文件)提供了证书,我们自己创建了 p12 文件。

通过在创建 p12 文件时指定 OpenSSL 参数 CSP,可以设置正确的 CSP。命令可能如下所示:
openssl pkcs12 -export -out Output.p12 -inkey My.key -in My.chain.pem -name My -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider"

如果您只有 p12 文件,您必须先将其从 PKCS10 格式转换为 PEM 格式,方法是调用:
openssl pkcs12 -in my.p12 -out my.pem

2。在应用程序启动时设置 AppContext 开关

如前所述,必须设置以下 AppContext 开关:

AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);

在我的例子中,我将开关设置在 class 深处的某处,我实际签署了 XML。所以当第一个网络请求被处理时,这段代码在运行时被执行。

在深入研究 System.Security.Cryptography.Xml.SignedXml 的内部结构时,我发现某些 AppContext 开关实际上已被缓存。我的更新太晚了。

现在我在应用程序启动时设置了开关,一切正常