Назад | Перейти на главную страницу

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 для отображения каких-либо сертификатов).

Затем журнал 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)

Вот что я пробовал:

Интересно, что если я попытаюсь подключиться через sqlcmd.exe, К сертификату претензий не поступало.

Я начинаю подозревать, что сертификаты с подстановочными знаками на сервере SQL будут загружен сервером, но нет экземпляра Клиент .NET SQL что может правильно работать против одного.

Может кто-нибудь пролить некоторый свет на это?


Обновить: Дополнительная информация о групповом сертификате:


Обновление 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 на сервере базы данных, функция подстановочных сертификатов по-прежнему не работает.