2015-08-20 3 views
1

Я работаю над некоторым кодом, который будет отправлять HTTP-запросы GET/POST на целевой сервер. Проблема возникает, когда приложение пытается установить соединение с защищенным сервером (https). Я использовал HttpsURLConnection для этой цели, как показано ниже:Отключить проверку сертификата для HttpsURLConnection, все еще получая javax.net.ssl.SSLHandshakeException: Полученное фатальное предупреждение: handshake_failure

url = new URL("https://www.sendspace.com/"); 
String input, htmlResponse = ""; 
HttpsURLConnection con; 

con = (HttpsURLConnection)url.openConnection(); 
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream())); 

while ((input = br.readLine()) != null){ 
    htmlResponse += input; 
} 
br.close(); 

однако, он показал следующее сообщение об ошибке:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

Поэтому я изменил код выше, как это:

url = new URL("https://www.sendspace.com/"); 
String input, htmlResponse = ""; 

SSLUtilities.trustAllHostnames(); 
SSLUtilities.trustAllHttpsCertificates(); 
HttpsURLConnection con; 
// code below has not been changed 

, который б/у SSLUtilities.java. Однако, я заметил, что делать это не имело никакого эффекта, так как я все-таки получил ту же самую ошибку, снова:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

Кроме того, я также попытался использовать другой подход, который связан с использованием SSLCertificateValidation.java с помощью этой линии до начиная с HttpsURLConnection:

SSLCertificateValidation.disable(); 

, и даже с использованием этой функции была получена такая же ошибка, как объяснялось ранее. Я хотел бы точно знать, почему этот подход не работает и как я могу обойти эту ошибку?

Пожалуйста, обратите внимание на следующее:

  1. Само собой разумеется, что я искал подробно по этому вопросу и уже потратили значительное количество времени, пробуя различные предложения и примеры кода, но безрезультатно. Я знаю, что эта ошибка много поднималась в вопросах, но мне не удалось найти конкретного ответа, который уже существует относительно моего собственного.

  2. Я знаю и понимаю проблемы безопасности, возникающие в результате отключения проверки сертификата. Однако, поскольку это приложение будет подключаться к 100-200 серверам (по мере необходимости), управление сертификатом для каждого сервера не представляется возможным. Поэтому, если кто-то не может указать метод (a) извлечения, (b) сохранения и (c) использование правильного сертификата для каждого сервера (во время выполнения), все из которых должно выполняться программно без какой-либо ручной работы, что «чистый» способ сделать это не является решением этого сценария.

Спасибо.

+1

Я пытался исследовать сертификат сервера, который я пытаюсь подключиться к, в приведенном выше (HTTPS примеров://www.sendspace.com/), и таким образом я нашел это: https://www.ssllabs.com/ssltest/analyze.html?d=sendspace.com, в котором четко говорится о проблеме во всех версиях Java с рукопожатием. Но это все еще не объясняет, почему попытки отключения проверки не работают. – Divulged

+0

Код, который вы цитируете, по крайней мере, 11 лет и имеет сомнительное качество. Классы 'com.sun.ssl. *' Не использовались с SSL с 1.4. – EJP

+0

@EJP: Я считаю, что вы имеете в виду код в SSLUtilities.java, а как насчет второго метода, который я использовал? Если это не сработает? И кроме того, вы могли бы направить меня на метод, который будет работать для моей цели? Благодарю. – Divulged

ответ

3

Ошибка рукопожатия не является ошибкой проверки сертификата, поэтому вы не можете ее исправить, игнорируя ошибки сертификата (это вообще-то плохая идея). Страница SSLLabs более четко определяет реальную причину проблемы:

Java 8u31 Protocol or cipher suite mismatch 

Если посмотреть на шифры, поддерживаемых сервером (опять же в отчете SSLLabs) вы можете увидеть, что все шифры содержат AES с ключом размером 256. Но в documentation about supported key sizes указано, что из-за ограничения на экспорт максимальный размер поддерживаемого ключа для AES составляет 128. Это означает, что ваш клиент предлагает только шифры AES128, тогда как сервер принимает только шифры AES256, то есть нет общих шифров.

Чтобы решить проблему, вы должны сделать, как описано в указанной документации:

If stronger algorithms are needed (for example, AES with 256-bit keys), the JCE Unlimited Strength Jurisdiction Policy Files must be obtained and installed in the JDK/JRE.

+0

Спасибо. Несмотря на то, что я знал о странице SSLLabs заранее, разница в длине ключа не возникла. Однако я хотел бы добавить к вышеупомянутому ответу еще несколько решений для людей, которые не хотят проходить ручную работу по добавлению файлов JCE в JDK/JRE. Для полного описания, пожалуйста, проверьте этот ответ: http://stackoverflow.com/a/22492582/4905539 – Divulged

+0

Спасибо. Я изменил свою платформу с 1.7 до 1.8, и теперь все работает. –

Смежные вопросы