SQL Server 登录前握手(错误:31 - 加密 (ssl/tls) 握手失败)

UTu*_*sta 9 c# sql-server azure azure-web-app-service asp.net-core

我在 .Net Core 3.1(或 6)Web Api 控制器中有一个 SQL Server 版本12.0.6205和以下代码:

 var builder = new SqlConnectionStringBuilder
{
    DataSource = DataSource,
    UserID = UserID,
    Password = Password,
    InitialCatalog = InitialCatalog,
    ApplicationIntent = ApplicationIntent.ReadWrite,
    
    // Same result if true/true
    Encrypt = false,
    TrustServerCertificate = false
};

var connection = new SqlConnection(builder.ToString());
using (var cmd = new SqlCommand() { Connection = connection, CommandText = "SELECT TOP 1 * FROM [dbo].[Table]" })
{
    connection.Open(); // Breaks here
    var reader = cmd.ExecuteReader();
    Console.WriteLine(reader.HasRows);
}
Run Code Online (Sandbox Code Playgroud)

在本地,此代码可以正常工作,但在 Azure 的应用程序服务中执行时,它会在使用以下命令打开连接时中断:

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)
Run Code Online (Sandbox Code Playgroud)

appsvc/dotnetcore如果创建基于(任何标签)的 docker 镜像,我也能够在本地重现该错误

FROM mcr.microsoft.com/appsvc/dotnetcore:3.1-latest_20220105.1

ENV ASPNETCORE_URLS=http://+:80  

EXPOSE 8080
WORKDIR /home/site/wwwroot/
COPY . .

ENTRYPOINT ["dotnet", "Test.dll"]
Run Code Online (Sandbox Code Playgroud)

UTu*_*sta 9

就像 @DraggonDragger 所说,这是一个 TLS 问题,但在我的具体情况下,我不能依赖更新的 SQL Server 来允许 TLS 1.2,因此我必须在应用程序中允许 TLS 1.0。

我最终遵循了这个答案:/sf/answers/4306633901/;

本质上,对于 docker 镜像,添加这一行就足够了: RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf

而对于Azure的App Service,我们可以添加 sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf && dotnet Test.dll启动命令。

为了供将来参考,GitHub 中也有关于此问题的讨论,链接