通配符证书(例如 *.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 应用程序,则通配符证书功能仍然不可用。