You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8连接SQL Server 2012时SSL/TLS握手失败求助

.NET 8连接SQL Server 2012预登录握手SSL/TLS失败问题解决

问题描述

从.NET 6升级至.NET 8以获取LTS支持,但暂无法升级SQL Server 2012,连接数据库时出现预登录握手阶段报错,提示SSL/TLS握手失败。

报错堆栈

System.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed)
 ---> System.IO.EndOfStreamException: End of stream reached
   ...(省略中间堆栈信息)
   at sqltest.Program.Main(String[] args) in /src/src/ConsoleAppConnectivity/Program.cs:line 29
ClientConnectionId:d974cac0-f1a3-4864-9867-17360db6e502

复现步骤

使用以下控制台应用及Dockerfile可复现问题:

控制台应用代码

using System.Data.SqlClient;

namespace sqltest
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var builder = new SqlConnectionStringBuilder
                {
                    DataSource = "<host>",
                    UserID = "<user>",
                    Password = "<pw>",
                    InitialCatalog = "<DB>",
                    TrustServerCertificate = true,
                    Encrypt = false
                };

                using SqlConnection connection = new(builder.ConnectionString);
                Console.WriteLine("\nQuery data example:");
                Console.WriteLine("=========================================\n");

                connection.Open();

                var sql = "SELECT top 10 * FROM dbo.<Table>";
                using SqlCommand command = new(sql, connection);
                using SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    Console.WriteLine("{0} {1}", reader.GetString(0), reader.GetString(1));
                }
            }
            catch (SqlException e)
            {
                Console.WriteLine(e.ToString());
            }
            Console.WriteLine("\nDone. Press enter.");
            Console.ReadLine();
        }
    }
}

Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
COPY certificates/ca/cert.pem /etc/ssl/certs/cert.pem
RUN update-ca-certificates

WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:8.0 as build
COPY certificates/ca/cert.pem /etc/ssl/certs/cert.pem
RUN update-ca-certificates

WORKDIR /src
COPY . . 

RUN dotnet restore src/ConsoleAppConnectivity --ignore-failed-sources
RUN dotnet build src/ConsoleAppConnectivity/ConsoleAppConnectivity.csproj -c Release -o /app --no-restore

FROM build AS publish
RUN dotnet publish src/ConsoleAppConnectivity/ConsoleAppConnectivity.csproj -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

# Recommended change to make it work
RUN sed -i 's/CipherString = DEFAULT@SECLEVEL=2/CipherString = DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf

ENTRYPOINT ["dotnet", "ConsoleAppConnectivity.dll"]

预期行为

成功查询并返回dbo.<Table>中的前10条记录。

技术环境

  • Microsoft.Data.SqlClient版本:5.1.2
  • .NET目标框架:8
  • SQL Server版本:2012(64位标准版)

已尝试操作

  • 测试多个.NET 8镜像均出现该问题,切换至.NET 5/6/7镜像及对应目标框架时连接正常;
  • 修改/etc/ssl/和/usr/lib/ssl/下的openssl.cnf,尝试添加/修改SECLEVEL、MinProtocol属性,但无效果;
  • 执行修改CipherString为DEFAULT@SECLEVEL=1的命令,未解决问题。

解决方案

1. 启用.NET对旧TLS协议的支持

.NET 8默认禁用了TLS 1.0和TLS 1.1,而未打SP4补丁的SQL Server 2012仅支持这些旧协议。可通过以下方式开启支持:

方式一:代码中添加配置

在Main方法开头加入:

// 启用旧版加密套件支持
AppContext.SetSwitch("System.Net.DontEnableSchUseStrongCrypto", true);
// 允许使用系统默认之外的旧TLS版本
AppContext.SetSwitch("System.Net.DontEnableSystemDefaultTlsVersions", true);

方式二:Docker环境变量配置

在Dockerfile的final阶段添加:

ENV DOTNET_SYSTEM_NET_DISABLESCHUSESTRONGCRYPTO=1
ENV DOTNET_SYSTEM_NET_DONTENABLESYSTEMDEFAULTTLSVERSIONS=1

2. 完整配置OpenSSL协议和加密级别

仅修改CipherString不足以解决问题,需确保OpenSSL允许SQL Server 2012支持的协议。将Dockerfile中的配置命令替换为:

RUN sed -i '/\[system_default_sect\]/a MinProtocol = TLSv1.0' /etc/ssl/openssl.cnf && \
    sed -i 's/CipherString = DEFAULT@SECLEVEL=2/CipherString = DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf

该命令会在system_default_sect节点下添加TLSv1.0支持,同时降低加密级别。

3. 升级SQL Server 2012的TLS支持(推荐)

若SQL Server 2012已安装SP4及后续累积更新,建议在服务器端启用TLS 1.2:

  • 修改服务器注册表,启用TLS 1.2并禁用旧协议;
  • 应用端连接字符串添加SslProtocol=Tls12,无需启用旧协议即可兼容。

4. 升级Microsoft.Data.SqlClient版本

将Microsoft.Data.SqlClient升级至最新稳定版(如5.2.x或更高),新版本可能修复了.NET 8下的兼容性问题。

内容的提问来源于stack exchange,提问作者Diego Sanabria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:47:10