尽管连接字符串中 TrustServerCertificate=true,SSL/证书验证错误

Bin*_*rus 2 sql-server oledb ssl connection-string

首先,请注意,我知道这个问题已经被问过好几次了。然而,到目前为止给出的已接受(和未接受)的解决方案在我的情况下不起作用,因此从那时起一定发生了一些实质性的变化,这希望有理由再次询问。

话虽如此:

我目前正在尝试将 Access 2010 .adp 应用程序升级到 Access 2019 .accdb。该应用程序包含大量的VBA代码,这些代码使用ADO对象来连接和操作Microsoft SQL Server(当前:2008 R2,但很快就会升级)。

我想保留大部分代码,这意味着坚持使用 ADO,所以要选择的方法是新的 OleDB SQL 服务器驱动程序(已弃用/2018 年新发布)。SQL 服务器在我的客户端应用程序之外的另一台计算机上运行。

我无法从 VBA 建立与 SQL Server 的连接。当执行以下代码片段时

Dim cnTemp As Connection
Set cnTemp = New Connection
cnTemp.CursorLocation = adUseServer
cntemp.Open "Provider=MSOLEDBSQL;Server=dbserver.example.com;Initial Catalog=MyDB;Authentication=SqlPassword;User ID=sa;Password=secret;DataTypeCompatibility=80;"
Run Code Online (Sandbox Code Playgroud)

执行最后一行时出现以下错误:

SSL 提供商:证书链由不受信任的机构颁发。

好的,没问题,毕竟我们发现了处理同一问题的所有其他问题,都提出了相同的解决方案:添加Trust Server Certificate=True;到连接字符串。

好吧,尝试过,但令我惊讶的是,情况仍然相同。然后我尝试了一些其他变体,例如TrustServerCertificate=True;或使用true而不是True,但无济于事。我还尝试添加Use Encryption for Data=True;这也没有帮助(这是可以预料的)。此外,我尝试了一些在研究问题时发现的片段,但 Microsoft 未记录这些片段在 ADO 连接字符串中有效(例如Encrypt=true或Trusted_Connection=true;);当然,这会使情况变得更糟,并引发其他错误消息。

我知道我可以通过将 SQL Server 证书放入客户端的受信任根证书存储中,或者让 SQL Server 使用由已知的受信任 CA(例如 Let's Encrypt)颁发的证书来解决该问题。

但是,我非常想知道为什么添加Trust Server Certificate=true;到我的连接字符串不会使错误消失,以及我必须在其中添加什么来禁用证书验证(顺便说一句,如果我们不开始,我将不胜感激关于为什么这会很糟糕的讨论;这只是在受信任的封闭网络中进行开发和测试,我知道可能存在的风险)。

Dan*_*man 9

TrustServerCertificate=True连接字符串不被遵守的原因有两个。一是它不是有效的 ADO 经典 (ADODB) 连接字符串关键字。根据ActiveX 数据对象 (ADO) 连接字符串关键字文档,关键字/值对应该是Trust Server Certificate=True(注意空格)。没有空格的关键字将被完全忽略,因此不被信任。

然而,由于规范的原因,仅此更改将不会信任该证书Authentication-SqlPassword。当Authentication指定关键字时,文档脚注会调用:

为了提高安全性,在使用身份验证/访问令牌初始化属性或其相应的连接字符串关键字时,会修改加密和证书验证行为。有关详细信息,请参阅加密和证书验证链接。

引用的链接包含以下重要说明:

还可以通过 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\SNI18.0\GeneralFlags\Flag2 注册表项的 Value 字段来控制证书验证。有效值为 0 或 1。OLE DB 驱动程序在注册表和连接属性/关键字设置之间选择最安全的选项。也就是说,只要至少一项注册表/连接设置启用服务器证书验证,驱动程序就会验证服务器证书。

因此,即使使用Trust Server Certificate=True,当此注册表值设置为 0 时,也会验证证书。

一种解决方案是简单地删除该Authentication=SqlPassword规范,只要您不需要通过不信任服务器证书来提供改进的安全性:

cntemp.Open "Provider=MSOLEDBSQL;Server=dbserver.example.com;Initial Catalog=MyDB;User ID=sa;Password=secret;Trust Server Certificate=True;DataTypeCompatibility=80;"
Run Code Online (Sandbox Code Playgroud)