You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

.NET 9 Docker容器中HTTPS请求遇“ca md too weak”SSL错误,配置忽略验证仍未解决的问题排查与咨询

.NET 9 Docker容器中HTTPS请求遇“ca md too weak”SSL错误,配置忽略验证仍未解决的问题排查与咨询

大家好,我最近在把一个.NET 9.0的代理应用容器化时遇到了一个棘手的SSL证书验证问题,想跟大家分享下排查过程和最终的解决方案,也给遇到类似问题的朋友提个醒。

问题现象

  • 本地MacOS环境运行应用完全正常,能正常发起HTTPS请求;
  • 部署到基于mcr.microsoft.com/dotnet/aspnet:9.0的Docker容器后,请求抛出SSL连接异常,核心错误是**ca md too weak**,完整错误栈如下:
Unhandled exception occurred System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+OpenSsl+SslException: Using SSL certificate failed with OpenSSL error - ca md too weak.
at Interop.OpenSsl.UpdateClientCertificate(SafeSslHandle ssl, SslAuthenticationOptions sslAuthenticationOptions)
at System.Net.Security.SslStreamPal.HandshakeInternal(SafeDeleteSslContext& context, ReadOnlySpan`1 inputBuffer, Int32& consumed, SslAuthenticationOptions sslAuthenticationOptions)

已尝试的无效配置

为了让应用完全忽略SSL证书验证错误,我做了多轮配置尝试,但都没有效果:

  1. 代码层面配置HttpClientHandler
    手动指定客户端证书,强制关闭证书验证回调,禁用吊销列表检查:
var handler = new HttpClientHandler {
    ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; },
    ClientCertificateOptions = ClientCertificateOption.Manual,
    ClientCertificates = { cert },
    CheckCertificateRevocationList = false
};
  1. Dockerfile中修改OpenSSL全局配置
    调整/etc/ssl/openssl.cnf的安全策略,降低SSL协议要求、放宽加密套件限制,甚至注释了CA证书验证相关配置:
RUN sed -i \
-e "s|^MinProtocol = .*|MinProtocol = TLSv1.0|g" \
-e "s|^CipherString = .*|CipherString = DEFAULT@SECLEVEL=0\nOptions = UnsafeLegacyRenegotiation,UnsafelyIgnoreCertCN,UnsafelyIgnoreHostVerification|g" \
-e "s|^VerifyCAFile =|#VerifyCAFile =|g" \
-e "s|^VerifyMode =|#VerifyMode =|g" \
/etc/ssl/openssl.cnf
RUN mkdir -p /usr/local/share/ca-certificates && \
touch /usr/local/share/ca-certificates/dummy.crt && \
update-ca-certificates
  1. 添加.NET环境变量禁用SSL验证
    设置了一堆.NET相关的环境变量,试图从框架层面跳过SSL证书检查、关闭HTTP2/3支持:
ENV DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=0
ENV DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_INSECURE=true
ENV DOTNET_NET_HTTP_SSL_CLIENT_CERT_MODE=Ignore
ENV DOTNET_NET_HTTP_SSL_SERVER_CERT_MODE=Ignore
ENV OPENSSL_CONF=/dev/null
ENV SSL_CERT_FILE=/dev/null
ENV SSL_CERT_DIR=/dev/null
ENV DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2SUPPORT=false
ENV DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP3SUPPORT=false

最终解决方案

最后我通过在代码中添加Linux平台特定的CryptoConfig配置解决了问题,代码如下:

if (OperatingSystem.IsLinux())
{
    CryptoConfig.AddAlgorithm(typeof(RSACryptoServiceProvider), "System.Security.Cryptography.RSA");
    CryptoConfig.AddAlgorithm(typeof(DSACryptoServiceProvider), "System.Security.Cryptography.DSA");
}

补充说明

这个问题的解决方案具有明显的平台相关性:MacOS环境下不需要这段代码就能正常运行,只有Linux容器环境才需要注册这两个加密算法。所以我认为这不是常规的SSL验证忽略问题的重复,特意分享出来帮助遇到同样问题的开发者。

火山引擎 最新活动