Сертификаты с подстановочными знаками (например, * .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 для отображения каких-либо сертификатов).
Затем журнал SQL Server сообщает мне, что все прошло довольно хорошо:
2010-08-31 11: 46: 04.04 Сервер Сертификат [Cert Hash (sha1) «5DDD9E51B30E0CA6CE3656AE54EC6D0B8B75904A»] успешно загружен для шифрования.
К сожалению, если я попытаюсь использовать Microsoft SQL Server Management Studio (версия 2008 R2) или классы Sql *, предоставленные в .NET Framework 4.0, я всегда получаю следующее исключение:
Соединение с сервером было успешно установлено, но затем произошла ошибка во время квитирования перед входом в систему. (поставщик: поставщик SSL, ошибка: 0 - CN-имя сертификата не соответствует переданному значению.) (Microsoft SQL Server, ошибка: -2146762481)
Вот что я пробовал:
prod
, и DNS-суффикс установлен правильно: prod.example.com
.)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.com
. Это было нарушением правил в версиях до 2008 R2, которое не позволяло SQL Server загрузить сертификат.prod.example.com
это то, что сейчас.Обновление 2: Так что это действительно запугает твой мозг:
Если я установил соединение через ODBC:
Собственный клиент Microsoft SQL Server версии 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();
}
}
Результат этой программы после замены имен пользователей и паролей, как это необходимо, на моем компьютере, следующий:
---------------------------------------- Trying SqlConnection... FAILED! System.Data.SqlClient.SqlException (0x80131904): A connection was successfully e stablished with the server, but then an error occurred during the pre-login hand shake. (provider: SSL Provider, error: 0 - The certificate's CN name does not ma tch the passed value.) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception , Boolean breakConnection) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() at System.Data.SqlClient.TdsParser.ConsumePreLoginHandshake(Boolean encrypt, Boolean trustServerCert, Boolean& marsCapable) at System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternal ConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Bool ean encrypt, Boolean trustServerCert, Boolean integratedSecurity) > ---------------------------------------- Trying OdbcConnection... SUCCESS! ----------------------------------------
Вот почему я пью.
Я знаю, что «select обычно не нарушается», но я не знаю, что с этим делать. Похоже, что SqlClient
классы в .NET Framework 4.0 просто не работают, когда дело доходит до проверки сертификатов с подстановочными знаками. Чем еще могут отличаться эти два метода?
Тот факт, что сертификат не появился в Configuration Tool, представляет собой первую проблему. Если сертификат установлен правильно, он должен появиться в этом списке. Где в хранилище сертификатов вы разместили сертификат? Он должен находиться в хранилище сертификатов локального компьютера в разделе «Личные»> «Сертификаты».
Вам также необходимо убедиться, что сертификат проверки подлинности сервера имеет свойство расширенного использования ключа сертификата, чтобы указать проверку подлинности сервера (1.3.6.1.5.5.7.3.1). Сертификат также должен быть создан с использованием параметра KeySpec для AT_KEYEXCHANGE, при желании вы можете установить свойство использования ключа, чтобы включить шифрование ключа.
Ответ от Microsoft заключается в том, что .NET SqlClient не будет работать с сертификатами с подстановочными знаками, точка.
Несмотря на то, что SQL Server 2008 R2 Express теперь поддерживает сертификаты с подстановочными знаками, а собственные поставщики были обновлены, чтобы понимать их (это означает ODBC и OLEDB), System.Data.SqlClient
классы в .NET Framework 4.0.
По сути, это означает, что если вы поддерживаете приложение .NET на сервере базы данных, функция подстановочных сертификатов по-прежнему не работает.