题 SQL Server 2008 R2 Express +通配符SSL证书


通配符证书(例如,* .example.com)在SQL Server 2008或更低版本中无法正常工作。但 加密与SQL Server的连接 在MSDN上的状态,就像白昼一样

SQL Server 2008 R2支持通配符证书。

优秀。所以我在一台机器上设置了SQL Server 2008 R2 Express,并配置了 HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQLServer\SuperSocketNetLib\Certificate 进入我的通配符SSL证书的指纹(因为在处理SQL服务器的五年中,我从来没有在Sql Server配置中获得#$ @#对话框来显示任何证书)。

然后SQL Server日志告诉我这很顺利:

2010-08-31 11:46:04.04服务器证书[Cert Hash(sha1)“5DDD9E51B30E0CA6CE3656AE54EC6D0B8B75904A”]已成功加载进行加密。

不幸的是,如果我尝试使用Microsoft SQL Server Management Studio(2008 R2版本)或.NET Framework 4.0中提供的Sql *类,我总是会收到以下异常:

已成功与服务器建立连接,但在登录前握手期间发生错误。 (提供程序:SSL提供程序,错误:0 - 证书的CN名称与传递的值不匹配。)(Microsoft SQL Server,错误:-2146762481)

以下是我尝试过的事情:

  • 确保正确配置主机名。 (例如,主机名是 prod,并正确设置DNS后缀: prod.example.com。)
  • 确保PTR记录 prod.example.com 正确设置。
  • 设置 TrustServerCertificate=Yes 在连接字符串中。

有趣的是,如果我尝试通过连接 sqlcmd.exe,我没有收到有关证书的投诉。

我开始怀疑SQL服务器中的通配符证书将是  由服务器,但没有实例 .NET SQL客户端 可以正确地对抗一个人。

任何人都可以对此有所了解吗?


更新:有关通配符证书的一些其他信息:

  • 是的,它安装在本地计算机>个人>证书中。
  • 它有了 Server Authentication (1.3.6.1.5.5.7.3.1) 增强的密钥用法。
  • 它有 Key Encipherment (a0) 哪里 (a0) 手段 AT_KEYEXCHANGE。 (它适用于FTP服务器和IIS网站,所以如果它被搞砸了,我想它不会在那里工作。)
  • 证书的主题是 CN = *.example.com (用“example”代替我们的工作领域)。也就是说,它被发给了 *.example.com。这是2008 R2之前版本中的交易破坏者,阻止了SQL Server加载证书。
  • 它有私钥。
  • 友好名称可以设置为任何 - prod.example.com 就是现在的样子。

更新2:所以这真的会炒你的大脑:

如果我通过ODBC建立连接:

Microsoft SQL Server Native Client版本10.50.1600

Data Source Name: prod.example.com
Data Source Description: prod
Server: tcp:prod.example.com,8484\SQLEXPRESS
Use Integrated Security: No
Database: (Default)
Language: (Default)
Data Encryption: Yes
Trust Server Certificate: No
Multiple Active Result Sets(MARS): No
Translate Character Data: Yes
Log Long Running Queries: No
Log Driver Statistics: No
Use Regional Settings: No
Use ANSI Quoted Identifiers: Yes
Use ANSI Null, Paddings and Warnings: Yes

然后我得到了一个成功的结果:

Microsoft SQL Server Native Client Version 10.50.1600

Running connectivity tests...

Attempting connection
Connection established
Verifying option settings
INFO: Connection was encrypted with server certificate validation.
Disconnecting from server

TESTS COMPLETED SUCCESSFULLY!

更新3:好的,在我放弃通配证书之前最后一次拍摄。这是我在C#中编写的一个示例程序:

    static void Main(string[] args)
    {
        Console.WriteLine(new string('-', 40));

        try
        {
            var connectionString = 
                @"Data Source=tcp:prod.example.com,8484\SQLEXPRESS; " +
                "User ID=ExampleDev;Password=ExamplePass; " +
                "Encrypt=True";

            Console.WriteLine("Trying SqlConnection...");

            using (var connection = new SqlConnection(connectionString))
            {
                connection.Open();

                Console.WriteLine("SUCCESS!");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("FAILED!");
            Console.WriteLine(e);
        }

        Console.WriteLine(new string('-', 40));

        try
        {
            var connectionString = 
                @"Driver={SQL Server Native Client 10.0}; " +
                "Server=tcp:prod.example.com,8484\SQLEXPRESS; " +
                "Uid=ExampleDev; Pwd=ExamplePass; Encrypt=yes";

            Console.WriteLine("Trying OdbcConnection...");

            using (var connection = new OdbcConnection(connectionString))
            {
                connection.Open();

                Console.WriteLine("SUCCESS!");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("FAILED!");
            Console.WriteLine(e);
        }

        Console.WriteLine(new string('-', 40));
        Console.ReadLine();
    }
}

在我的机器上运行之后,在替换用户名和密码之后,该程序的输出如下:

----------------------------------------
尝试SqlConnection ...
失败!
System.Data.SqlClient.SqlException(0x80131904):连接成功e
与服务器一起建立,但在登录前的手中发生了错误
抖动。 (提供者:SSL提供者,错误:0  - 证书的CN名称不是ma
tch传递的值。)
   在System.Data.SqlClient.SqlInternalConnection.OnError(SqlException异常
,Boolean breakConnection)
   在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   在System.Data.SqlClient.TdsParser.ConsumePreLoginHandshake(布尔加密,
Boolean trustServerCert,Boolean&marsCapable)
   在System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo,SqlInternal
ConnectionTds connHandler,Boolean ignoreSniOpenTimeout,Int64 timerExpire,Bool
ean encrypt,Boolean trustServerCert,Boolean integratedSecurity)
   >
----------------------------------------
尝试OdbcConnection ...
成功!
----------------------------------------

这就是我喝酒的原因。

我知道“选择通常不会被打破”,但我不知道该怎么做。好像是 SqlClient 在验证通配符证书时,.NET Framework 4.0中的类刚刚被破坏。 这两种方法之间还有什么不同?


5
2017-08-31 16:40




(另外,我不确定这是否应该在StackOverflow上。它似乎可以桥接两个问题域。) - Nicholas Piasecki
我认为这对SF或SO来说没问题,所以我们现在就把它留在这里。 - mrdenny
“这就是我喝酒的原因” - 哦,我们不是在某个时候都去过那里 - pauska


答案:


证书未显示在配置工具中的事实是第一个问题。如果证书安装正确,那么它应该显示在该列表中。你在证书商店的哪个地方放了证书?它应位于“个人”>“证书”下的“本地计算机”证书存储区中。

您还需要确保服务器身份验证证书具有证书的增强型密钥用法属性,以指定服务器身份验证(1.3.6.1.5.5.7.3.1)。还必须使用AT_KEYEXCHANGE的KeySpec选项创建证书,您可以选择将密钥用法属性设置为包括密钥加密。


3
2017-08-31 18:25



谢谢回复。我已经用附加信息更新了这个问题。说实话,即使在成功使用第三方SSL证书的服务器上,我也从未在下拉列表中看到任何内容。再次感谢! - Nicholas Piasecki
当您通过sqlcmd测试它时,您是否通过wireshark或其他任何方式验证会话是否已加密? - mrdenny
好的调用...对于sqlcmd.exe,如果我不使用-N参数(“加密连接”,那么在Microsoft网络监视器3.4中,我可以看到我的查询以明确的方式在带有“TCP Continued Payload”描述的帧上传递当我添加-N时,我看到了乱码和“SSL应用程序数据”,它告诉我它是加密的。我做了进一步的实验,发现如果它的CN与服务器完全匹配,我可以得到下拉列表来显示证书;它会似乎这个对话框可能没有更新支持通配符证书。我想知道sqlcmd是否使用了不同的库。 - Nicholas Piasecki
它应该使用SQL 2008 R2本机客户端(或客户端计算机上安装的任何版本)。因此,当您尝试两个提供程序时,只有Native Client工作。我认为只有Native客户端已经更新。 ODBC是老派,OLEDB(SQL Native Client)应该用于新工作。 - mrdenny
给你答案A的努力;微软的答案是本机客户端支持它,但.NET客户端(甚至是Management Studio!)不支持它。 - Nicholas Piasecki


微软的答案 是因为.NET SqlClient不能用于通配符证书,期间。

即使SQL Server 2008 R2 Express现在支持通配符证书,并且本机提供程序已更新以了解它们(这意味着ODBC和OLEDB), System.Data.SqlClient .NET Framework 4.0中的类。

从本质上讲,这意味着如果您支持针对数据库服务器的.NET应用程序,通配符证书功能仍然是不行的。


1
2017-09-02 22:28