当前位置:   article > 正文

异常:A connection was successfully established with the server, but then an error occurred during the

a connection was successfully established with the server, but then an error

.net6在linux环境中连接部分低版本的sqlserver出现报错:

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)

解决方案:

(1)linux配置ssl降级,参考连接:centos下 连接sqlserver (provide:SSL Provider,error:31 - Encryption(ssl/tls) handshake failed)-腾讯云开发者社区-腾讯云

(2)将system.Data.SqlClient包替换为Microsoft.Data.SqlClient3.0.1

 注意,需要将引用也换了
4002492f957e45fb9b9c7404de4ea399.png

(3)链接字符串修改:TrustServerCertificate=true;Encrypt=false;

网上的资料不多,很多说改连接字符串内容的,对我的情况无效,单独将linux中的openssl降级也无效,几种一起上才行,我觉得这里的主要起作用的还是sqlclient包降级。

原因:为什么包一降级就行了?是否高级别的sqlclient强制使用了某些加密的密码套件而sqlserver不支持这些密码套件?这里涉及的知识我不了解,搞不清来龙去脉,有懂得朋友可以指点一下

---更新---

最近学习计算机网络后,联想到这个报错,再次分析一下:
sqlserver的数据库连接,使用的微软自家的TDS协议,这个协议是基于SSL/TLS的。根据报错最后的内容:Encryption(ssl/tls) handshake failed。可以得知是在建立TLS连接的时候握手失败了。

下面贴张图大概讲解一下TLS连接的原理:

cc500e61a51f42c4a0c7b7f60615151b.jpeg

TLS连接分为握手和会话阶段,以下文字来源于课本内容:(讲讲握手阶段,毕竟报错已经明确说明了是握手失败)

***************

我们先介绍协议 TLS的握手阶段。握手阶段包括:(1)协商加密算法,(2)服务器鉴别,(3)生成主密钥,(4)服务器用自己的私钥把主密钥解密出来

(重点内容)
(1)协商加密算法客户A向服务器B发送自己选定的加密算法(包括密钥交换算法)。服务器B从中确认自己所支持的算法,同时把自己的CA数字证书发送给A。这里要说明一下,从TLS1.0更新到1.1和 1.2版本时,每一次更新都增加了当时认为是更加安全可靠的加密算法。为了协议的向后兼容,对老版本中的不太安全的数十种算法也都保留下来了。这就造成协商过程非常耗时,需要花费2倍RTT的时间(通常记为2-RTT)。因此最新的TLS 1.3版本把陈旧的很多种算法统统取消(例如MD5,SHA-1,DES,3DES等),只留下几种最安全的算法。客户不是把自己所有的加密算法都告诉服务器,供服务器来挑选,而是猜测服务器可能愿意使用什么加密算法,把自己选定的加密算法直接发送给服务器,让服务器来确认。这就把“协商”时间缩短为1-RTT。


(2)服务器鉴别    客户 A用数字证书中CA的公钥对数字证书进行验证鉴别。


(3)生成主密钥    客户A按照双方确定的密钥交换算法生成主密钥MS(Master Secret)。客户 A用B的公钥PKB对主密钥MS加密,得出加密的主密钥PKB(MS),发送给服务器 B。请注意,在有关TLS的文档中,密钥一词使用的是Secret,而不是Key。


(4)服务器B用自己的私钥把主密钥解密出来:SKn(PKa(MS)) =MS。这样,客户A和服务器B都拥有了为后面的数据传输使用的共同的主密钥MS。

**************

根据上面这段话中的橙色字体的内容,得知不同的TLS版本支持的加密方法是不一样的,我的场景中,服务器的sqlserver版本非常古老。估计只支持TLS1,而客户端用的是.net6,环境是linux,所以此处需要linux配置ssl降级,原来默认是TLS1.3。

可是为什么sqlclient包需要降级呢???

还有为什么不降级的情况下,在windows系统可以正常连接sqlserver服务器?(难道是windows默认是TLS1.0的配置)

文中提到:客户不是把自己所有的加密算法都告诉服务器,供服务器来挑选,而是猜测服务器可能愿意使用什么加密算法,把自己选定的加密算法直接发送给服务器,让服务器来确认。

这里的决定发送哪几种加密算法的“客户”,是指的操作系统,还是应用程序?

这些问题我暂时没有确切答案。如果有知道的朋友可以指点一下

关于sqlserver和tls的官方信息

https://learn.microsoft.com/zh-cn/troubleshoot/sql/database-engine/connect/tls-1-2-support-microsoft-sql-server

--------再次更新------

之前以为这个连接问题只会出现在linux上,结果今天在Windows上也出现了

客户端:windows系统,使用java连接sqlserver

服务器端:sqlserver2012

这次在客户端,使用c#连接sqlserver时正常连接,而切换到java则报tls协议不一致错误。

从这一点起码排除了操作系统的干扰。我把java版本切换到1.8,还是报错(之前是21)

之后从网上找到方法,修改java.securety文件里的参数(实际是因为默认的配置里禁用了tls1.0和1.1的加密算法,修改配置实际上是把这些加密算法启用,这样的话,客户端在握手时,就会把这些加密算法发给服务器,让服务器从里面选一个它支持的算法)。

从这一点看,应用层也能够控制使用哪些算法来进行jtls握手。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/601773
推荐阅读
相关标签
  

闽ICP备14008679号