Почему рукопожатие SSL дает исключение «Не удалось создать пару ключей DH»? - PullRequest
135 голосов
/ 28 июля 2011

Когда я устанавливаю SSL-соединение с некоторыми IRC-серверами (но не с другими - предположительно из-за предпочтительного метода шифрования сервера), я получаю следующее исключение:

Caused by: java.lang.RuntimeException: Could not generate DH keypair
    at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:106)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:556)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:183)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
    ... 3 more

Конечная причина:

Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
    at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:100)
    ... 10 more

Примером сервера, демонстрирующего эту проблему, является aperture.esper.net:6697 (это сервер IRC).Примером сервера, который не демонстрирует проблему, является kornbluth.freenode.net:6697.[Не удивительно, что все серверы в каждой сети имеют одинаковое соответствующее поведение.]

Мой код (который, как отмечалось, работает при подключении к некоторым серверам SSL):

    SSLContext sslContext = SSLContext.getInstance("SSL");
    sslContext.init(null, trustAllCerts, new SecureRandom());
    s = (SSLSocket)sslContext.getSocketFactory().createSocket();
    s.connect(new InetSocketAddress(host, port), timeout);
    s.setSoTimeout(0);
    ((SSLSocket)s).startHandshake();

Это такпоследний стартHandshake, который выбрасывает исключение.И да, с «trustAllCerts» происходит какая-то магия;этот код заставляет систему SSL не проверять сертификаты.(Так что ... не проблема.)

Очевидно, что одна из возможностей заключается в неправильной настройке сервера esper, но я искал и не нашел никаких других ссылок на людей, имеющих проблемы с портами SSL esper, и 'opensslподключается к нему (см. ниже).Поэтому мне интересно, является ли это ограничением поддержки SSL по умолчанию в Java или чем-то еще.Любые предложения?

Вот что происходит, когда я подключаюсь к aperture.esper.net 6697 с помощью 'openssl' из командной строки:

~ $ openssl s_client -connect aperture.esper.net:6697
CONNECTED(00000003)
depth=0 /C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
verify return:1
---
Certificate chain
 0 s:/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
   i:/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
---
Server certificate
-----BEGIN CERTIFICATE-----
[There was a certificate here, but I deleted it to save space]
-----END CERTIFICATE-----
subject=/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
issuer=/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
---
No client certificate CA names sent
---
SSL handshake has read 2178 bytes and written 468 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 51F1D40A1B044700365D3BD1C61ABC745FB0C347A334E1410946DCB5EFE37AFD
    Session-ID-ctx: 
    Master-Key: DF8194F6A60B073E049C87284856B5561476315145B55E35811028C4D97F77696F676DB019BB6E271E9965F289A99083
    Key-Arg   : None
    Start Time: 1311801833
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---

Как уже отмечалось, после этого он действительно успешно соединяется, чтоэто больше, чем вы можете сказать для моего приложения Java.

Если это уместно, я использую OS X 10.6.8, версия Java 1.6.0_26.

Ответы [ 21 ]

4 голосов
/ 22 марта 2018

Возможно, у вас неверные зависимости Maven.Вы должны найти эти библиотеки в иерархии зависимостей Maven:

bcprov-jdk14, bcpkix-jdk14, bcmail-jdk14

Если у вас есть эти зависимости, что является ошибкой, и вы должны сделать это:

Добавить зависимость:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcmail-jdk15on</artifactId>
    <version>1.59</version>
</dependency>

Исключите эти зависимости из артефакта, который включал неправильные зависимости, в моем случае это:

<dependency>
    <groupId>com.lowagie</groupId>
    <artifactId>itext</artifactId>
    <version>2.1.7</version>
    <exclusions>
        <exclusion>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bctsp-jdk14</artifactId>                
        </exclusion>
        <exclusion>
            <groupId>bouncycastle</groupId>
            <artifactId>bcprov-jdk14</artifactId>               
        </exclusion>
        <exclusion>
            <groupId>bouncycastle</groupId>
            <artifactId>bcmail-jdk14</artifactId>               
        </exclusion>
    </exclusions>       
</dependency>
2 голосов
/ 21 ноября 2015

У меня такая же проблема с сервером Карт Яндекса, JDK 1.6 и Apache HttpClient 4.2.1. Ошибка была

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

с включенной отладкой -Djavax.net.debug=all в журнале было сообщение

Could not generate DH keypair

Я исправил эту проблему, добавив библиотеку BouncyCastle bcprov-jdk16-1.46.jar и зарегистрировав провайдера в классе картографических услуг

public class MapService {

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public GeocodeResult geocode() {

    }

}

Провайдер регистрируется при первом использовании MapService.

1 голос
/ 16 марта 2017

Я столкнулся с ошибкой SSL на сервере CentOS с JDK 6.

Я планировал установить более высокую версию JDK (JDK 7) для сосуществования с JDK 6, но оказалось, что простая установкаболее нового JDK с rpm -i было недостаточно.

Установка JDK 7 будет успешной только с опцией обновления rpm -U, как показано ниже.

1.Загрузить JDK 7

wget -O /root/jdk-7u79-linux-x64.rpm --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; o raclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.rpm"

2.Сбой установки RPM

rpm -ivh jdk-7u79-linux-x64.rpm
Preparing...                ########################################### [100%]
        file /etc/init.d/jexec from install of jdk-2000:1.7.0_79-fcs.x86_64 conflicts with file from package jdk-2000:1.6.0_43-fcs.x86_64

3.Обновление RPM выполнено успешно

rpm -Uvh jdk-7u79-linux-x64.rpm
Preparing...                ########################################### [100%]
   1:jdk                    ########################################### [100%]
Unpacking JAR files...
        rt.jar...
        jsse.jar...
        charsets.jar...
        tools.jar...
        localedata.jar...
        jfxrt.jar...

4.Подтвердите новую версию

java -version
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
1 голос
/ 05 января 2017

Я использую coldfusion 8 на JDK 1.6.45, и у меня были проблемы с предоставлением мне только красных крестиков вместо изображений, а также с cfhttp, не способным подключиться к локальному веб-серверу с помощью ssl.

мой тестовый скрипт дляВоспроизведение с помощью Coldfusion 8 было

<CFHTTP URL="https://www.onlineumfragen.com" METHOD="get" ></CFHTTP>
<CFDUMP VAR="#CFHTTP#">

. Это дало мне довольно общую ошибку «Исключение ввода-вывода: одноранговый узел не аутентифицирован».Затем я попытался добавить сертификаты сервера, включая корневые и промежуточные сертификаты, в хранилище ключей java, а также в хранилище ключей coldfusion, но ничего не помогло.затем я отладил проблему с

java SSLPoke www.onlineumfragen.com 443

и получил

javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair

и

Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be
multiple of 64, and can only range from 512 to 1024 (inclusive)
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
    at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:107)
    ... 10 more

У меня тогда возникла мысль, что веб-сервер (apache в моем случае)У него очень современные шифры для ssl, и он довольно ограничен (квалификационный балл +) и использует сильные ключи diffie hellmann с более чем 1024 битами.Очевидно, Coldfusion и Java JDK 1.6.45 не может справиться с этим.Следующим шагом в odysee было подумать об установке альтернативного провайдера безопасности для Java, и я выбрал надувной замок.см. также http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/

Затем я скачал

bcprov-ext-jdk15on-156.jar

из http://www.bouncycastle.org/latest_releases.html и установил его в C: \ jdk6_45 \ jre \ lib \ ext или где-либо еще ваш jdkв оригинальной установке coldfusion 8 это будет в C: \ JRun4 \ jre \ lib \ ext, но я использую более новый jdk (1.6.45), расположенный вне каталога coldfusion.очень важно поместить bcprov-ext-jdk15on-156.jar в каталог \ ext (это стоило мне около двух часов и немного волос ;-), затем я отредактировал файл C: \ jdk6_45 \ jre \ lib \ security \java.security (с wordpad, а не с editor.exe!) и поместите в одну строку для нового поставщика.после этого список выглядел как

#
# List of providers and their preference orders (see above):
#
security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.2=sun.security.provider.Sun
security.provider.3=sun.security.rsa.SunRsaSign
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.mscapi.SunMSCAPI

(см. новый в позиции 1)

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

java SSLPoke www.onlineumfragen.com 443 (or of course your url!)

и наслаждаться ощущением ... и, конечно,

какая ночь и какой день.Надеюсь, это поможет (частично или полностью) кому-то там.если у вас есть вопросы, просто напишите мне на info ... (домен выше).

1 голос
/ 01 июня 2016

Решил проблему путем обновления до JDK 8.

0 голосов
/ 08 августа 2018

Недавно у меня возникла та же проблема, и после обновления версии jdk с 1.6.0_45 до jdk1.7.0_191 , которая разрешила проблему.

0 голосов
/ 07 января 2017

Раньше я получал похожую ошибку при доступе к svn.apache.org с Java-клиентами Java с использованием IBM JDK.В настоящее время svn.apache.org использует настройки шифрования клиентов.

После однократного запуска с перехватом пакетов / javax.net.debug = ALL я смог внести в черный список только один шифр DHE, и у меня все работает(ECDHE согласовывается вместо этого).

.../java/jre/lib/security/java.security:
    jdk.tls.disabledAlgorithms=SSL_DHE_RSA_WITH_AES_256_CBC_SHA

Хорошее быстрое исправление, когда изменить клиента нелегко.

0 голосов
/ 05 декабря 2016

Я получил эту ошибку с Bamboo 5.7 + Gradle project + Apache. Gradle попытался получить некоторые зависимости от одного из наших серверов через SSL.

Решение:

  1. Создать параметр DH:

с OpenSSL:

openssl dhparam 1024

пример вывода:

-----BEGIN DH PARAMETERS-----
MIGHfoGBALxpfMrDpImEuPlhopxYX4L2CFqQov+FomjKyHJrzj/EkTP0T3oAkjnS
oCGh6p07kwSLS8WCtYJn1GzItiZ05LoAzPs7T3ST2dWrEYFg/dldt+arifj6oWo+
vctDyDqIjlevUE+vyR9MF6B+Rfm4Zs8VGkxmsgXuz0gp/9lmftY7AgEC
-----END DH PARAMETERS-----
  1. Добавить вывод в файл сертификата (для Apache - SSLCertificateFile param)

  2. Перезапустить apache

  3. Перезагрузка бамбука

  4. Попробуйте построить проект снова

0 голосов
/ 18 октября 2016

Для меня следующая командная строка устранила проблему:

java -jar -Dhttps.protocols=TLSv1.2 -Ddeployment.security.TLSv1.2=true -Djavax.net.debug=ssl:handshake XXXXX.jar

Я использую JDK 1.7.0_79

0 голосов
/ 05 апреля 2016

Мы получили точно такую ​​же ошибку исключения, исправить которую было легко после нескольких часов серфинга в интернете.

Мы скачали самую высокую версию jdk, которую мы могли найти на oracle.com, установили ее и указали приложение Jbossсервер в каталог установленного нового jdk.

Перезапущен Jboss, переработан, проблема исправлена ​​!!!

...