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

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 Server 的五年里,我从未在 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。)
  • 确保prod.example.com正确设置了 PTR 记录。
  • TrustServerCertificate=Yes在连接字符串中设置。

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

我开始怀疑 SQL Server 中的通配符证书将会已加载由服务器,但没有实例.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.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):已成功建立连接
与服务器建立连接,但在登录前处理过程中发生错误
摇晃。(提供者:SSL 提供者,错误:0 - 证书的 CN 名称不代表
tch 传递的值。)
   在 System.Data.SqlClient.SqlInternalConnection.OnError (SqlException 异常
,布尔值 breakConnection)
   在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   在 System.Data.SqlClient.TdsParser.ConsumePreLoginHandshake(布尔加密,
布尔 trustServerCert,布尔& marsCapable)
   在 System.Data.SqlClient.TdsParser.Connect (ServerInfo serverInfo,SqlInternal
ConnectionTds connHandler,布尔值 ignoreSniOpenTimeout,Int64 timerExpire,布尔值
ean 加密,布尔 trustServerCert,布尔 IntegratedSecurity)
   >
----------------------------------------
正在尝试 OdbcConnection...
成功!
----------------------------------------

这就是我喝酒的原因。

我知道“select 通常不会出错”,但我不知道该怎么解释。似乎SqlClient.NET Framework 4.0 中的类在验证通配符证书时出错了。这两种方法还有什么不同?

答案1

证书未显示在配置工具中这一事实带来了第一个问题。如果证书安装正确,则它应该显示在列表中。您将证书放在证书存储的哪个位置?它应该位于本地计算机的证书存储中的个人 > 证书下。

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

答案2

微软的答案.NET SqlClient 不适用于通配符证书,就是这样。

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

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

相关内容