Драйверу не удалось установить безопасное соединение с sql server используя шифрование ssl

Обновлено: 07.07.2024

При подключении к базе данных SQL Server с ошибкой Microsoft JDBC появляется следующая ошибка:

com.microsoft.sqlserver.jdbc.SQLServerException: драйвер не смог установить безопасное соединение с SQL Server с использованием шифрования Secure Sockets Layer (SSL). Ошибка: "SQL Server вернул неполный ответ. Соединение было закрыто. ClientConnectionId: 98d0b6f4-f3ca-4683-939e-7c0a0fca5931".

Недавно мы обновили наши приложения с Java 6 и Java 7 до Java 8. На всех системах под управлением Java работают SUSE Linux Enterprise Server 11 (x86_64), VERSION = 11, PATCHLEVEL = 3.

Вот факты, которые я собрал с помощью программы Java, которую я написал, которая просто последовательно открывается и закрывает 1000 соединений с базой данных.

  • Связи отбрасываются с этой ошибкой примерно на 5% -10% времени. Ошибка не возникает при каждом подключении.
  • Проблема ТОЛЬКО возникает с Java 8. Я запускал ту же программу на Java 7, и проблема не воспроизводима. Это соответствует нашему опыту в производстве до обновления. У нас были нулевые проблемы, запущенные под Java 7 в производстве.
  • Проблема не возникает на всех наших Linux-серверах под управлением Java 8, это происходит только на некоторых из них. Это меня озадачивает, но когда я запускаю одну и ту же тестовую программу на той же версии Linux JVM (1.8.0_60, 64 бит) в разных экземплярах Linux, проблема не возникает в одном из экземпляров Linux, но проблема происходит на других. В экземплярах Linux работает одна и та же версия SUSE, и они находятся на одном уровне исправлений.
  • Проблема возникает при подключении к серверам/базам данных BOTH SQL Server 2008 и SQL Server 2014.
  • Проблема возникает независимо от того, использую ли я версию 4.0 JDBC для SQL Server или версию версии 4.1 для версии 4.0.

То, что делает мои наблюдения уникальными по сравнению с другими в Интернете, заключается в том, что хотя проблема происходит ТОЛЬКО на Java 8, я не могу решить эту проблему на одном из кажущихся идентичными Linux-серверов, на которых работает тот же Java 8 JVM. Другие люди также видели эту проблему в более ранних версиях Java, но это не наш опыт.

Любые ввод, предложения или наблюдения, которые вы, возможно, цените.

ОТВЕТЫ

Ответ 1

Обходной путь, который мы используем в работе и который доказал свою эффективность для нас, заключается в установке этого параметра в JVM:

Если вы хотите больше подробностей, пожалуйста, читайте дальше.

На сервере, где проблема может быть воспроизведена (опять же, только 5-10% времени), я заметил следующее:

Обратите внимание, что TLSv1.2 выбирается сервером базы данных и используется в этом обмене. Я заметил, что при сбое соединения из проблемной службы linux TLSv1.2 ВСЕГДА является выбранным уровнем. Тем не менее, соединения не ВСЕГДА терпят неудачу при использовании TLSv1.2. Они терпят неудачу только 5-10% времени.

Теперь вот обмен с сервера, который не имеет проблемы. Все остальное равно. Т.е., подключение к той же базе данных, той же версии JVM (Java 1.8.0_60), тому же драйверу JDBC и т.д. Обратите внимание, что здесь TLSv1 выбирается сервером базы данных вместо TLSv1.2, как в случае неисправного сервера.

Таким образом, когда TLSv1 согласовывается между Linux JVM и SQL Server, соединения ВСЕГДА успешны. Когда согласовывается TLSv1.2, мы получаем спорадические сбои соединения.

(Примечание: Java 7 (1.7.0_51) всегда согласовывает TLSv1, поэтому у нас никогда не возникало проблем с Java 7 JVM.)

У нас остаются открытые вопросы:

  1. ПОЧЕМУ одна и та же Java 8 JVM, запущенная на 2 разных серверах Linux, всегда будет согласовывать TLSv1, но при подключении с другого сервера Linux она всегда согласовывает TLSv1.2.
  2. А также почему согласованные соединения TLSv1.2 успешны большую часть, но не все, времени на этом сервере?

Обновление 10/10/2017: эта публикация от Microsoft описывает проблему и ее предлагаемое решение.

Ресурсы:

Ответ 2

Похоже, что это было исправлено в версии 4.2 драйвера MS SQL JDBC. Я создал программу, в которой я подключался к серверу 1000 раз, делая паузу в 100 мс между каждой попыткой. С версией 4.1 мне удавалось воспроизвести проблему каждый раз, хотя это происходило лишь время от времени. С версией 4.2 мне не удалось воспроизвести проблему.

Ответ 3

Перед обновлением драйвера SQL JDBC сначала проверьте совместимость:

  • Sqljdbc.jar требует JRE из 5 и поддерживает API JDBC 3.0
  • Sqljdbc4.jar требует JRE 6 и поддерживает API JDBC 4.0
  • Sqljdbc41.jar требует JRE 7 и поддерживает API JDBC 4.1
  • Sqljdbc42.jar требует JRE 8 и поддерживает API JDBC 4.2

Ответ 4

Недавно Microsoft открыла свой драйвер. В GitHub можно увидеть mssql-jdbc активность драйвера. Я предполагаю, что последняя версия предварительного просмотра - 6.1.5.

Также вы можете найти все версии предварительного просмотра на maven. Поддержка JDK7 и JDK 8.

Ответ 5

Я также затронул эту проблему в Windows Server 2012 R2, используя драйвер JDBC 4.0 и 4.1 с Java 7. Это статья Microsoft вины в DHE ciphersuites и рекомендует отключать их или уменьшать их приоритет, если вы не можете перейти на драйвер JDBC 4.2

Ответ 6

В моем случае это была java-версия, начиная с java 8 upgrade 171, переходите на java 8 upgrade 111, она также работает с java 8 upgrade 14X

Ответ 7

Ваш URL должен быть как ниже и добавить sql sqljdbc42.jar. Это решит вашу проблему

Я получаю следующую ошибку при подключении к базе данных SQL Server с использованием версии драйвера JDBC Microsoft:

com.Microsoft.sqlserver.jdbc.SQLServerException: драйверу не удалось установить безопасное соединение с SQL Server с использованием шифрования Secure Sockets Layer (SSL). Ошибка: «SQL Server возвратил неполный ответ. Соединение было закрыто. ClientConnectionId: 98d0b6f4-f3ca-4683-939e-7c0a0fca5931».

Недавно мы обновили наши приложения с Java 6 и Java 7 до Java 8. Все системы, работающие на Java, работают под управлением SUSE Linux Enterprise Server 11 (x86_64), VERSION = 11, PATCHLEVEL = 3.

Вот факты, которые я собрал с помощью написанной мной Java-программы, которая просто последовательно открывает и закрывает 1000 подключений к базе данных.

  • Соединения сбрасываются с этой ошибкой примерно 5% -10% времени. Ошибка НЕ ​​возникает на каждом соединении.
  • Проблема возникает ТОЛЬКО с Java 8. Я запустил ту же программу на Java 7, и проблема не воспроизводима. Это соответствует нашему опыту производства до модернизации. У нас было ноль проблем при работе под Java 7 на производстве.
  • Проблема не возникает на всех наших серверах Linux, работающих под управлением Java 8, она возникает только на некоторых из них. Это сбивает с толку меня, но когда я запускаю одну и ту же тестовую программу на одной и той же версии Linux JVM (1.8.0_60, 64-битная) на разных экземплярах Linux, проблема не возникает ни на одном из экземпляров Linux, но проблема действительно происходит на других. Экземпляры Linux работают под одной и той же версией SUSE и находятся на одном уровне исправлений.
  • Проблема возникает при подключении к ОБА SQL Server 2008 и SQL Server 2014 серверов/баз данных.
  • Проблема возникает независимо от того, использую ли я версию 4.0 драйвера JDBC для SQL Server или более новую версию драйвера 4.1.

Что делает мои наблюдения уникальными в этом отношении по сравнению с другими в Интернете, так это то, что, хотя проблема возникает ТОЛЬКО на Java 8, я не могу получить проблему на одном из, казалось бы, идентичных серверов Linux, на котором установлена ​​та же Java 8 JVM. Другие люди видели эту проблему и в более ранних версиях Java, но это не наш опыт.

Будем благодарны за любые комментарии, предложения или замечания.

Обходной путь, который мы используем в работе и доказал свою эффективность для нас, заключается в установке этого параметра в JVM:

Если вы хотите больше подробностей, пожалуйста, читайте дальше.

На сервере, где проблема может быть воспроизведена (опять же, только 5-10% времени), я заметил следующее:

Обратите внимание, что TLSv1.2 выбирается сервером базы данных и используется в этом обмене. Я заметил, что при сбое подключения из проблемной службы linux TLSv1.2 ВСЕГДА является выбранным уровнем. Тем не менее, соединения не ВСЕГДА терпят неудачу при использовании TLSv1.2. Они терпят неудачу только 5-10% времени.

Теперь вот обмен с сервера, который не имеет проблемы. Все остальное равно. Т.е. подключение к той же базе данных, той же версии JVM (Java 1.8.0_60), тому же драйверу JDBC и т.д. Обратите внимание, что здесь сервер баз данных выбирает TLSv1 вместо TLSv1.2, как в Дело неисправного сервера.

Таким образом, когда TLSv1 согласовывается между Linux JVM и SQL Server, соединения ВСЕГДА успешны. Когда согласовывается TLSv1.2, мы получаем спорадические сбои соединения.

(Примечание: Java 7 (1.7.0_51) всегда согласовывает TLSv1, поэтому у нас никогда не возникало проблем с Java 7 JVM.)

У нас остаются открытые вопросы:

  1. ПОЧЕМУ одна и та же Java 8 JVM, запущенная на 2 разных серверах Linux, всегда будет согласовывать TLSv1, но при подключении с другого сервера Linux она всегда согласовывает TLSv1.2.
  2. А также, почему согласованные соединения TLSv1.2 успешны большую часть, но не все, времени на этом сервере?

Update 6/10/2017:Эта публикация от Microsoft описывает проблему и предлагаемое решение.

Я получаю следующую ошибку при подключении к базе данных SQL Server с помощью версии драйвера Microsoft JDBC:

com.Microsoft.от SQLServer.интерфейс jdbc.SQLServerException: драйвер не удалось установить безопасное соединение с SQL Server с помощью шифрования Secure Sockets Layer (SSL). Ошибка: "SQL Server вернул неполный ответ. Соединение было закрыто. ClientConnectionId: 98d0b6f4-f3ca-4683-939e-7c0a0fca5931".

мы недавно обновил наши приложения с Java 6 и Java 7 до Java 8. Все системы под управлением Java работают под управлением SUSE Linux Enterprise Server 11 (x86_64), VERSION = 11, PATCHLEVEL = 3.

вот факты, которые я собрал с помощью Java-программы, которую я написал, которая просто последовательно открывает и закрывает соединения с базой данных 1,000.

  • соединения удаляются с этой ошибкой около 5%-10% времени. Ошибка возникает не при каждом подключении.
  • проблема Происходит только с Java 8. Я запустил ту же программу на Java 7, и проблема не воспроизводима. Это соответствует нашему опыту в производстве до модернизации. У нас было ноль проблем работает под Java 7 в производстве.
  • проблема не возникает на всех наших серверах Linux под управлением Java 8, она возникает только на некоторых из них. Это озадачивает меня, но когда я запускаю ту же тестовую программу на той же версии Linux JVM (1.8.0_60, 64 бит) на разных Linux экземпляры, проблема не возникает на одном из экземпляров Linux, но проблема возникает на других. Экземпляры Linux работают под управлением той же версии SUSE и находятся на том же уровне исправлений.
  • проблема возникает при подключении к серверам/базам данных SQL Server 2008 и SQL Server 2014.
  • проблема возникает независимо от того, использую ли я версию 4.0 драйвера JDBC SQL Server или более новую версию драйвера 4.1.

в что делает мои наблюдения уникальными по сравнению с другими в интернете, так это то, что, хотя проблема возникает только на Java 8, я не могу получить проблему на одном из, казалось бы, идентичных серверов Linux, на котором работает тот же Java 8 JVM. Другие люди видели эту проблему и в более ранних версиях Java, но это не было нашим опытом.

любые входные данные, предложения или замечания, которые у вас могут быть оценены.

на решение что мы используем в продукции и доказывало работать для нас установить этот параметр на JVM:

если вы хотите больше деталей, то пожалуйста прочитайте дальше.

на сервере, где проблема может быть воспроизведена (опять же, только 5-10% время), я заметил следующее:

обратите внимание, что в протоколе TLSv1.2 выбирается сервером базы данных и используется в этом обмене. Я заметил, что, когда соединения терпят неудачу от проблемной службы linux, TLSv1.2-это всегда выбранный уровень. Однако соединения не всегда завершаются с ошибкой при TLSv1.2 используется. Они не только 5-10% времени.

теперь вот обмен с сервера, который не имеет проблемы. Все остальное равно. То есть, подключение к той же базе данных, той же версии JVM (Java 1.8.0_60), того же драйвера JDBC и т. д. Обратите внимание, что здесь, в протоколе TLSv1 выбирается сервером базы данных вместо TLSv1.2 как в случае неисправного сервера.

таким образом, когда TLSv1 согласовывается между JVM Linux и SQL Server, соединения всегда успешны. Когда TLSv1.2 обсуждается, мы получаем спорадические сбои соединения.

(Примечание: Java 7 (1.7.0_51) всегда согласовывает TLSv1, поэтому проблема никогда не возникала для нас с Java 7 JVM.)

открытые вопросы, у нас еще есть:

  1. почему тот же Java 8 JVM, запущенный с 2 разных серверов Linux, всегда будет согласовывать TLSv1, но при подключении с другого сервера Linux он всегда согласовывает TLSv1.2.
  2. а также почему TLSv1.2 согласованные соединения успешны в большинстве случаев, но не во всех случаях на этом сервере?

Я получаю следующую ошибку при подключении к базе данных SQL Server с использованием версии драйвера Microsoft JDBC:

com.microsoft.sqlserver.jdbc.SQLServerException: драйверу не удалось установить безопасное соединение с SQL Server с помощью шифрования Secure Sockets Layer (SSL). Ошибка: «SQL Server вернул неполный ответ. Соединение было закрыто. ClientConnectionId: 98d0b6f4-f3ca-4683-939e-7c0a0fca5931».

Недавно мы обновили наши приложения с Java 6 и Java 7 до Java 8. Все системы, на которых работает Java, работают под управлением SUSE Linux Enterprise Server 11 (x86_64), VERSION = 11, PATCHLEVEL = 3.

Вот факты, которые я собрал с помощью написанной мной программы на Java, которая просто последовательно открывает и закрывает 1000 соединений с базой данных.

  • Соединения обрываются с этой ошибкой примерно в 5-10% случаев. Ошибка НЕ ​​возникает при каждом подключении.
  • Проблема возникает ТОЛЬКО с Java 8. Я запускал ту же программу на Java 7, и проблема не воспроизводится. Это соответствует нашему опыту производства до модернизации. У нас не было никаких проблем с работой под Java 7 в производственной среде.
  • Проблема НЕ возникает на всех наших серверах Linux под управлением Java 8, она возникает только на некоторых из них. Это вызывает у меня недоумение, но когда я запускаю одну и ту же тестовую программу на той же версии Linux JVM (1.8.0_60, 64 бит) на разных экземплярах Linux, проблема возникает не на одном из экземпляров Linux, а проблема происходит на других. Экземпляры Linux используют одну и ту же версию SUSE и имеют одинаковый уровень исправлений.
  • Проблема возникает при подключении к ОБЕИМ серверам / базам данных SQL Server 2008 и SQL Server 2014.
  • Проблема возникает независимо от того, использую ли я версию драйвера JDBC для SQL Server 4.0 или более новую версию драйвера 4.1.

То, что делает мои наблюдения уникальными по сравнению с другими в Интернете, заключается в том, что, хотя проблема возникает ТОЛЬКО на Java 8, я не могу добиться, чтобы проблема возникла на одном из, казалось бы, идентичных серверов Linux, на которых работает та же Java 8 JVM. Другие люди видели эту проблему и в более ранних версиях Java, но мы не сталкивались с этим.

Мы будем благодарны за любые комментарии, предложения или замечания.

Временное решение , которое мы используем в производственной среде и которое доказало свою эффективность, заключается в установке этого параметра на JVM:

Если вы хотите получить более подробную информацию, продолжайте читать.

На сервере, где проблема может быть воспроизведена (опять же, только в 5-10% случаев), я наблюдал следующее:

Обратите внимание, что TLSv1.2 выбран сервером базы данных и используется в этом обмене. Я заметил, что при сбое подключения из-за проблемной службы Linux TLSv1.2 ВСЕГДА является выбранным уровнем. Однако при использовании TLSv1.2 соединения не ВСЕГДА завершаются сбоем. Они терпят неудачу только в 5-10% случаев.

Теперь вот обмен с сервера, у которого нет проблемы. В остальном все равно. Т.е. подключение к той же базе данных, той же версии JVM (Java 1.8.0_60), тому же драйверу JDBC и т. Д. Обратите внимание, что здесь сервер базы данных выбирает TLSv1 вместо TLSv1.2. как в случае неисправного сервера.

Таким образом, когда TLSv1 согласовывается между Linux JVM и SQL Server, соединения ВСЕГДА успешны. Когда согласовывается TLSv1.2, мы получаем спорадические сбои подключения.

(Примечание: Java 7 (1.7.0_51) всегда согласовывает TLSv1, поэтому проблема никогда не возникала у нас с Java 7 JVM.)

У нас все еще есть нерешенные вопросы:

  1. ПОЧЕМУ одна и та же JVM Java 8, запущенная с двух разных серверов Linux, всегда согласовывает TLSv1, но при подключении с другого сервера Linux всегда согласовывает TLSv1.2.
  2. А также почему согласованные соединения TLSv1.2 являются успешными в большинстве, но не всегда, на этом сервере?

Читайте также: