Сбой рукопожатия SSL - Java 1.8
Просто сообщаю людям о проблеме, которая возникла у многих после обновления до Java 1.8. Не все решения одинаковы, поэтому я пишу, как я решил эту проблему.
Но сначала... Это не решение, достойное производственных систем, поскольку безопасность эффективно снижается. Однако, если вы заблокированы тестированием и т. Д., Это, вероятно, вполне подходит
Моя проблема была в том, что независимо от того, что я сделал... включил SSLv3 и т. Д. Я всегда получал
"javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure".
Вот шаги, которые я предпринял, чтобы "решить" это.
Сначала я обнаружил, какой шифр использует сервер. Я сделал это через openssl.
openssl s_client -host yourproblemhost.com -port 443
Это дает (в конце...)
SSL-Session:
Protocol : TLSv1.2
Cipher : RC4-MD5
Теперь... что мы используем "Java-мудрый", чтобы включить этот шифр?
В этой ссылке есть имена и их Java-аналог. Так что для RC4-MD5 у нас есть SSL_RSA_WITH_RC4_128_MD5.
хорошо. Теперь я добавил системное свойство.
-Dhttps.cipherSuites=SSL_RSA_WITH_RC4_128_MD5
И в моем коде...
Security.setProperty("jdk.tls.disabledAlgorithms", "" /*disabledAlgorithms */ );
Опять же... это абсолютное последнее средство "исправить"... Но если вы бьете головой о стену, чтобы запустить ее (для тестирования), я надеюсь, что она пригодится.
3 ответа
В версии JDK 1.8.0_51 RC4 больше не поддерживается из Java как клиент (также как сервер) для согласования SSL-квитирования, RC4 считается слабым (и скомпрометированным) шифром, и это является причиной удаления
http://bugs.java.com/view_bug.do?bug_id=8076221
Однако вы можете включить его, удалив RC4 из jdk.tls.disabledAlgorithms
из вашей конфигурации безопасности Java или программно включить их с помощью setEnabledCipherSuites()
метод
Однако лучшим решением будет обновить конфигурацию сервера (если он находится под вашим контролем), чтобы перейти на более мощные шифры
RC4 теперь считается взломанным шифром. Наборы шифров RC4 были удалены из списка набора шифров по умолчанию как для клиента, так и для сервера в реализации Oracle JSSE. Эти наборы шифров могут быть включены
SSLEngine.setEnabledCipherSuites()
а такжеSSLSocket.setEnabledCipherSuites()
методы.
Что касается вашего подхода к настройке с помощью Security.setProperty()
, это ненадежный способ, потому что поля, которые содержат отключенные алгоритмы, являются статическими и окончательными, поэтому, если этот класс загружается первым, у вас нет контроля над ним, вы можете попробовать создать файл свойств.
как это
## override it to remove RC4, in disabledcipher.properties
jdk.tls.disabledAlgorithms=DHE
и в вашей JVM вы можете ссылаться на это как системное свойство, как это
java -Djava.security.properties=disabledcipher.properties blah...
RC4 был эффективно взломан - 14 лет назад.
Атака Флюрера, Мантина и Шамира (FMS), опубликованная в их статье 2001 года "Слабые стороны в алгоритме планирования ключей RC4", использует слабость алгоритма планирования ключей RC4 для восстановления ключа из зашифрованных сообщений.
Проблема не в Java 8.
Проблема в том, что ваш сервер использует RC4.
Обратите внимание, что основной причиной здесь является сервер. Я только опубликовал это, чтобы обеспечить обходной путь, пока серверы (которые вполне могут быть вне контроля разработчика) могут быть исправлены
Спасибо Alton за то, что поделился такой информацией о спасении жизни. Только одно я хотел бы изменить с тех пор
openssl s_client -host yourproblemhost.com -port 443
returned ->
Protocol : TLSv1.2
Cipher : 0000
openssl s_client -connect X.X.X.X:993 -prexit -tls1
returned -> the expected response as
Protocol : TLSv1
Cipher : RC4-MD5