Почему при подтверждении SSL возникает исключение «Не удалось создать пару ключей DH»?

144

Когда я устанавливаю 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();

Это последний startHandshake, который вызывает исключение. И да, с 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.

Сэм
источник
2
Причина , кажется, это: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive). Понятия не имею, какой размер был отправлен сюда сервером и что об этом говорится в спецификации.
Palo Ebermann
@ PaŭloEbermann: На самом деле вы можете увидеть размер сервера, использованного в opensslвыводе, в вопросе: «Шифр - DHE-RSA-AES256-SHA, открытый ключ сервера - 2048 бит». И 2048> 1024 :-).
sleske
@sleske: не совсем так. Server public key (size)был и остается ключом в сертификате. s_clientв 2011 году вообще не показывал эфемерный ключ; 1.0.2 в 2015 году и выше на Server Temp Keyнесколько строк выше. Хотя хороший сервер обычно должен делать размер DHE таким же, как размер RSA-auth.
dave_thompson_085

Ответы:

119

Проблема в простом размере. Максимально допустимый размер, который принимает Java, составляет 1024 бита. Это известная проблема (см. JDK-6521495 ).

В отчете об ошибке, на который я ссылался, упоминается обходной путь с использованием реализации JCE BouncyCastle. Надеюсь, это сработает для вас.

ОБНОВИТЬ

Об этом сообщалось как об ошибке JDK-7044060, и она была недавно исправлена.

Обратите внимание, однако, что предел был увеличен только до 2048 бит. Для размеров> 2048 бит есть JDK-8072452 - Удалить максимальный простой размер ключей DH ; исправление похоже на 9.

Вивин Палиат
источник
15
+1. Все, у кого есть учетная запись Sun Developer Network, пожалуйста, проголосуйте за эту ошибку.
Palo Ebermann
1
Спасибо. Кажется довольно серьезной проблемой, учитывая существование серверов, которые запрашивают больший размер! :( Я пробовал BouncyCastle; если вы настроили его как предпочтительного поставщика, он вылетает с другим исключением (вздох), и я не вижу очевидного способа использовать это только для DH. Однако я нашел альтернативное решение, которое я добавлю как новый ответ (это некрасиво)
sam
3
Круто. Это было исправлено в новых версиях Java. Но у меня вопрос об использовании более старой версии. Когда я использую старую версию, иногда она работает, а иногда дает указанное выше исключение. Почему такое случайное поведение? Если это ошибка в java, я думаю, она никогда не должна работать?
N ..
2
Исправление 2048 было перенесено в IcedTea 2.5.3. В новых версиях IcedTea он увеличен до
4096.
1
Проблема заключается в простом размере DH. Максимально допустимый размер, который принимает Java, составляет 2048 бит. Пока мы ждем, пока Oracle расширит лимит, вы можете выполнить компиляцию с помощью Excelsior Jet, у которого есть расширенный лимит.
user1332994
68

Ответ «Файлы политики юрисдикции с неограниченной надежностью расширения Java Cryptography (JCE)» не сработал для меня, но предложение поставщика JCE от BouncyCastle сработало.

Вот шаги, которые я предпринял, используя Java 1.6.0_65-b14-462 на Mac OSC 10.7.5.

1) Загрузите эти банки:

2) переместите эти банки в $ JAVA_HOME / lib / ext

3) отредактируйте $ JAVA_HOME / lib / security / java.security следующим образом: security.provider.1 = org.bouncycastle.jce.provider.BouncyCastleProvider

перезапустите приложение с помощью JRE и попробуйте

mjj1409
источник
12
security.provider.2 = org.bouncycastle.jce.provider.BouncyCastleProvider действительно работал лучше, 1. его включение привело к ошибкам в программном обеспечении по умолчанию.
TinusSky 07
1
У меня это тоже работает, но я добавил поставщика динамически. Повторите мой ответ здесь, чтобы узнать подробности.
v.ladynev
Большое спасибо, это сработало для меня и потребовалось для успешной сборки исходного кода Tomcat 7.0.78.
phillipuniverse
@ mjj1409, в Java 1.5 у нас нет пути $ JAVA_HOME / lib / security
Мостафа,
16

Вот мое решение (java 1.6), тоже было бы интересно, почему я должен был это сделать:

Я заметил из javax.security.debug = ssl, что иногда используемый набор шифров - это TLS_DHE _..., а иногда это TLS_ECDHE _..... Позднее произойдет, если я добавлю BouncyCastle. Если был выбран TLS_ECDHE_, БОЛЬШИНСТВО времени он работал, но не ВСЕГДА, поэтому добавление даже поставщика BouncyCastle было ненадежным (сбой с той же ошибкой, каждый раз или около того). Я предполагаю, что где-то в реализации Sun SSL иногда выбирается DHE , иногда ECDHE .

Таким образом, размещенное здесь решение основано на полном удалении шифров TLS_DHE_. ПРИМЕЧАНИЕ: BouncyCastle НЕ требуется для решения.

Итак, создайте файл сертификации сервера:

echo |openssl s_client -connect example.org:443 2>&1 |sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

Сохраните это, поскольку на него будут ссылаться позже, чем будет решение для получения SSL http, за исключением наборов шифров TLS_DHE_.

package org.example.security;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

import org.apache.log4j.Logger;

public class SSLExcludeCipherConnectionHelper {

    private Logger logger = Logger.getLogger(SSLExcludeCipherConnectionHelper.class);

    private String[] exludedCipherSuites = {"_DHE_","_DH_"};

    private String trustCert = null;

    private TrustManagerFactory tmf;

    public void setExludedCipherSuites(String[] exludedCipherSuites) {
        this.exludedCipherSuites = exludedCipherSuites;
    }

    public SSLExcludeCipherConnectionHelper(String trustCert) {
        super();
        this.trustCert = trustCert;
        //Security.addProvider(new BouncyCastleProvider());
        try {
            this.initTrustManager();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void initTrustManager() throws Exception {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream caInput = new BufferedInputStream(new FileInputStream(trustCert));
        Certificate ca = null;
        try {
            ca = cf.generateCertificate(caInput);
            logger.debug("ca=" + ((X509Certificate) ca).getSubjectDN());
        } finally {
            caInput.close();
        }

        // Create a KeyStore containing our trusted CAs
        KeyStore keyStore = KeyStore.getInstance("jks");
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);
    }

    public String get(URL url) throws Exception {
        // Create an SSLContext that uses our TrustManager
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);
        SSLParameters params = context.getSupportedSSLParameters();
        List<String> enabledCiphers = new ArrayList<String>();
        for (String cipher : params.getCipherSuites()) {
            boolean exclude = false;
            if (exludedCipherSuites != null) {
                for (int i=0; i<exludedCipherSuites.length && !exclude; i++) {
                    exclude = cipher.indexOf(exludedCipherSuites[i]) >= 0;
                }
            }
            if (!exclude) {
                enabledCiphers.add(cipher);
            }
        }
        String[] cArray = new String[enabledCiphers.size()];
        enabledCiphers.toArray(cArray);

        // Tell the URLConnection to use a SocketFactory from our SSLContext
        HttpsURLConnection urlConnection =
            (HttpsURLConnection)url.openConnection();
        SSLSocketFactory sf = context.getSocketFactory();
        sf = new DOSSLSocketFactory(sf, cArray);
        urlConnection.setSSLSocketFactory(sf);
        BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
        String inputLine;
        StringBuffer buffer = new StringBuffer();
        while ((inputLine = in.readLine()) != null) 
            buffer.append(inputLine);
        in.close();

        return buffer.toString();
    }

    private class DOSSLSocketFactory extends javax.net.ssl.SSLSocketFactory {

        private SSLSocketFactory sf = null;
        private String[] enabledCiphers = null;

        private DOSSLSocketFactory(SSLSocketFactory sf, String[] enabledCiphers) {
            super();
            this.sf = sf;
            this.enabledCiphers = enabledCiphers;
        }

        private Socket getSocketWithEnabledCiphers(Socket socket) {
            if (enabledCiphers != null && socket != null && socket instanceof SSLSocket)
                ((SSLSocket)socket).setEnabledCipherSuites(enabledCiphers);

            return socket;
        }

        @Override
        public Socket createSocket(Socket s, String host, int port,
                boolean autoClose) throws IOException {
            return getSocketWithEnabledCiphers(sf.createSocket(s, host, port, autoClose));
        }

        @Override
        public String[] getDefaultCipherSuites() {
            return sf.getDefaultCipherSuites();
        }

        @Override
        public String[] getSupportedCipherSuites() {
            if (enabledCiphers == null)
                return sf.getSupportedCipherSuites();
            else
                return enabledCiphers;
        }

        @Override
        public Socket createSocket(String host, int port) throws IOException,
                UnknownHostException {
            return getSocketWithEnabledCiphers(sf.createSocket(host, port));
        }

        @Override
        public Socket createSocket(InetAddress address, int port)
                throws IOException {
            return getSocketWithEnabledCiphers(sf.createSocket(address, port));
        }

        @Override
        public Socket createSocket(String host, int port, InetAddress localAddress,
                int localPort) throws IOException, UnknownHostException {
            return getSocketWithEnabledCiphers(sf.createSocket(host, port, localAddress, localPort));
        }

        @Override
        public Socket createSocket(InetAddress address, int port,
                InetAddress localaddress, int localport) throws IOException {
            return getSocketWithEnabledCiphers(sf.createSocket(address, port, localaddress, localport));
        }

    }
}

Наконец, вот как он используется (certFilePath, если путь сертификата сохранен из openssl):

try {
            URL url = new URL("https://www.example.org?q=somedata");            
            SSLExcludeCipherConnectionHelper sslExclHelper = new SSLExcludeCipherConnectionHelper(certFilePath);
            logger.debug(
                    sslExclHelper.get(url)
            );
        } catch (Exception ex) {
            ex.printStackTrace();
        }
Zsozso
источник
11
Просто протестировал ваше решение. Он работает как задумано. Спасибо. На самом деле, просто добавив jdk.tls.disabledAlgorithms=DHE, ECDHEв JDK_HOME/jre/lib/security/java.securityтоже работает и избежать всего этого кода.
Людовик Гийом
4
Просто отключив ДНО работало для меня jdk.tls.disabledAlgorithms=DHE. Используя 1.7.0_85-b15.
Стефан Ф
1
Добавлен jdk.tls.disabledAlgorithms = DHE, ECDHE в JDK_HOME / jre / lib / security / java.security и работал нормально! Спасибо! Использование 1.7.0_79
Эрик На,
2
Не отключайте ECDHE. Он отличается от DHE и даже не использует простые числа.
kubanczyk 08
1
Кто-нибудь может сказать мне, как я могу получить certFilePath. Я застрял на этом неделю. @Zsozso
user1172490
13

Приведенный выше ответ правильный, но с точки зрения обходного пути у меня возникли проблемы с реализацией BouncyCastle, когда я установил его в качестве предпочтительного поставщика:

java.lang.ArrayIndexOutOfBoundsException: 64
    at com.sun.crypto.provider.TlsPrfGenerator.expand(DashoA13*..)

Это также обсуждается в одной ветке форума, которую я нашел, в которой не упоминается решение. http://www.javakb.com/Uwe/Forum.aspx/java-programmer/47512/TLS-problems

Я нашел альтернативное решение, которое работает в моем случае, хотя оно меня совсем не устраивает. Решение состоит в том, чтобы настроить его так, чтобы алгоритм Диффи-Хеллмана был вообще недоступен. Затем, если сервер поддерживает альтернативный алгоритм, он будет выбран во время обычного согласования. Очевидно, обратная сторона этого состоит в том, что если кому-то каким-то образом удастся найти сервер, который поддерживает только Diffie-Hellman на 1024 битах или меньше, то это фактически означает, что он не будет работать там, где он работал раньше.

Вот код, который работает с SSLSocket (до его подключения):

List<String> limited = new LinkedList<String>();
for(String suite : ((SSLSocket)s).getEnabledCipherSuites())
{
    if(!suite.contains("_DHE_"))
    {
        limited.add(suite);
    }
}
((SSLSocket)s).setEnabledCipherSuites(limited.toArray(
    new String[limited.size()]));

Противно.

Сэм
источник
1
Печально, что это единственный способ :(. Этот билет был открыт с 2007 года. Странно, что ничего не было сделано с этим за 4 года.
Вивин Палиат
Я новичок в ценных бумагах Java. Пожалуйста, помогите, где мне написать этот фрагмент кода?
Шашанк
Я пробовал все решения в этом потоке, и это было единственное, которое работало с моим ibm jvm (ibm-java-s390x-60).
Джанлука Греко
@Sam, какая переменная в ((SSLSocket) s)?
Мостафа
13

Вы можете полностью отключить DHE в своем jdk, отредактировать jre / lib / security / java.security и убедиться, что DHE отключен, например. подобно

jdk.tls.disabledAlgorithms=SSLv3, DHE.

Tor
источник
4
это доступно только в JDK 1.7 и новее. link
hoangthienan
Решил проблему для меня JDK 1.8.0_144-b01
MrSmith42
12

Вы можете установить провайдера динамически:

1) Загрузите эти банки:

  • bcprov-jdk15on-152.jar
  • bcprov-ext-jdk15on-152.jar

2) Скопируйте банки в WEB-INF/lib(или в ваш путь к классам)

3) Добавить провайдера динамически:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

Security.addProvider(new BouncyCastleProvider());

ангелкоррал
источник
Это решение работает хорошо и хорошо подходит для моего случая, поскольку я хотел внести изменения только на уровне проекта, а не на уровне сервера / среды. Спасибо
ishanbakshi 04
Благодарность! это сработало для меня. В моем случае это был itext, импортировавший bcp 1.4, что привело к сбою электронных писем в Google.
Иафет Онгери - инкалимева
Я получаю javax.net.ssl.SSLHandshakeException: Unsupported curveId: 29 with java version 1.6.0_27
Другой кодер
6

Если вы используете jdk1.7.0_04, обновитесь до jdk1.7.0_21. В этом обновлении проблема исправлена.

Lekkie
источник
2
Я только что загрузил Java SE Development Kit 7u25, и, согласно небольшой программе, которую я написал для определения максимального поддерживаемого размера DH , он все еще 1024.
user2666524
1
Проблема все еще существует с JDK 1.7.0_25
Себастьен Ванмехелен
обновление jre сработало для меня. had 6.22 обновился до 7.59. задача решена.
Элазарон
1
@Shashank - У меня сработало обновление до JDK 1.8.0_73.
dgoverde
DHKeyPairs с битовой длиной больше 1024 введены в JDK 1.7.0_91, но недоступны для всех.
Другой кодер
6

Возможно, у вас неправильные зависимости 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>
Хосе Антонио Санчес Пуханте
источник
Вопрос уже получил много ответов и имеет один подтвержденный ответ. Тем более, что вопрос был задан более 6 лет назад. Я не уверен, что это все еще актуально.
Дэвид Гайон
5

Попробуйте загрузить "Файлы политики юрисдикции неограниченной надежности Java Cryptography Extension (JCE)" с сайта загрузки Java. и заменить файлы в своей JRE.

У меня это сработало, и мне даже не пришлось использовать BouncyCastle - стандартный Sun JCE мог подключаться к серверу.

PS. У меня такая же ошибка (ArrayIndexOutOfBoundsException: 64), когда я пытался использовать BouncyCastle перед изменением файлов политики, поэтому, похоже, наша ситуация очень похожа.

Mjomble
источник
ты делал что-нибудь еще? или просто скопировал 2 файла в папку?
Joergi
Это было давно, но насколько я помню, это все, что мне нужно было сделать. Помимо перезапуска любых запущенных процессов Java после этого.
mjomble
5

Если вас все еще беспокоит эта проблема, И вы используете Apache httpd v> 2.4.7, попробуйте следующее: http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh

скопировано с URL :

Начиная с версии 2.4.7, mod_ssl будет использовать параметры DH, которые включают простые числа длиной более 1024 бит. Однако Java 7 и более ранние версии ограничивают поддержку простых размеров DH до 1024 бит.

Если ваш клиент на основе Java прерывает работу с такими исключениями, как java.lang.RuntimeException: не удалось сгенерировать пару ключей DH и java.security.InvalidAlgorithmParameterException: основной размер должен быть кратен 64 и может находиться в диапазоне от 512 до 1024 (включительно), и httpd регистрирует внутреннюю ошибку предупреждения tlsv1 (номер предупреждения SSL 80) (на уровне информации LogLevel или выше), вы можете изменить список шифров mod_ssl с помощью SSLCipherSuite (возможно, в сочетании с SSLHonorCipherOrder), или вы можете использовать настраиваемые параметры DH с 1024-битным простым числом , который всегда будет иметь приоритет над любым из встроенных параметров DH.

Чтобы сгенерировать специальные параметры DH, используйте

openssl dhparam 1024

команда. В качестве альтернативы вы можете использовать следующие стандартные 1024-битные параметры DH из RFC 2409, раздел 6.2:

-----BEGIN DH PARAMETERS-----
MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR
Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL
/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC
-----END DH PARAMETERS-----

Добавьте пользовательские параметры, включая строки «BEGIN DH PARAMETERS» и «END DH PARAMETERS», в конец первого файла сертификата, который вы настроили с помощью директивы SSLCertificateFile.


Я использую java 1.6 на стороне клиента, и это решило мою проблему. Я не понижал комплекты шифров и т.п., но добавил настраиваемый параметр DH в файл сертификата.

pka
источник
Имейте в виду, что сейчас считается, что 1024-битный DH можно взломать с вычислительной точки зрения (хотя и чертовски дорого).
plugwash 02
2

У меня такая же проблема с сервером Яндекс Карты, 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.

В.Ладынев
источник
2

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

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

Установка 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

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

анре
источник
1

Я использую 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 или где-либо еще, в исходной установке 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)

затем полностью перезапустите службу coldfusion. тогда ты можешь

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

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

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

Рафаэль Мейер
источник
0

Если сервер поддерживает шифр, который не включает DH, вы можете заставить клиента выбрать этот шифр и избежать ошибки DH. Такие как:

String pickedCipher[] ={"TLS_RSA_WITH_AES_256_CBC_SHA"};
sslsocket.setEnabledCipherSuites(pickedCipher);

Имейте в виду, что указание точного шифра в конечном итоге может выйти из строя.

Джейсон Мартин
источник
0

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

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

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

Питер Азука Молокву
источник
0

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

Решение:

  1. Создать DH Param:

с OpenSSL:

openssl dhparam 1024

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

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

  2. Перезагрузите apache

  3. Перезапустить Bamboo

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

Евгений Лебедев
источник
0

Раньше я получал аналогичную ошибку при доступе к svn.apache.org с помощью клиентов java SVN с использованием 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

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

Сэм
источник
-1

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

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

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

Рико-Чанго
источник
1
Я столкнулся с такой же ситуацией, используя JDK 1.7.0_xx. По умолчанию проблема будет решена после использования jdk 1.8. Но иногда мы не можем быстро обновить jdk. Итак, моя проблема решена после добавления конфигурации системы: System.setProperty ("https.protocols", "TLSv1.2"); System.setProperty ("deployment.security.TLSv1.2", "true");
Рамгау 02