Dlaczego uzgadnianie SSL generuje wyjątek „Nie można wygenerować pary kluczy DH”?

142

Kiedy nawiązuję połączenie SSL z niektórymi serwerami IRC (ale nie z innymi - prawdopodobnie ze względu na preferowaną metodę szyfrowania serwera) pojawia się następujący wyjątek:

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

Ostateczna przyczyna:

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

Przykładem serwera, który demonstruje ten problem jest aperture.esper.net:6697 (to jest serwer IRC). Przykładem serwera, który nie demonstruje problemu, jest kornbluth.freenode.net:6697. [Nic dziwnego, że wszystkie serwery w każdej sieci zachowują się tak samo.]

Mój kod (który, jak wspomniano, działa podczas łączenia się z niektórymi serwerami SSL) to:

    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();

To ostatni startHandshake rzuca wyjątek. I tak, z „trustAllCerts” dzieje się jakaś magia; ten kod wymusza na systemie SSL, aby nie weryfikował certyfikatów. (Więc ... nie jest to pewien problem.)

Oczywiście jedną z możliwości jest to, że serwer espera jest źle skonfigurowany, ale przeszukałem i nie znalazłem żadnych innych odniesień do osób mających problemy z portami SSL espera i łączy się z nim „openssl” (patrz poniżej). Zastanawiam się więc, czy to jest ograniczenie domyślnej obsługi SSL w Javie, czy coś. Jakieś sugestie?

Oto, co się dzieje, gdy łączę się z aperture.esper.net 6697 za pomocą „openssl” z wiersza poleceń:

~ $ 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)
---

Jak już wspomniano, po tym wszystkim łączy się pomyślnie, co jest czymś więcej niż możesz powiedzieć o mojej aplikacji Java.

Jeśli ma to znaczenie, używam OS X 10.6.8, Java w wersji 1.6.0_26.

sam
źródło
2
Przyczyną wydaje się być to: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive). Nie mam pojęcia, jaki rozmiar przesłał tutaj serwer i co mówi o tym specyfikacja.
Paŭlo Ebermann
@ PaŭloEbermann: Właściwie rozmiar serwera używanego w danych opensslwyjściowych można zobaczyć w pytaniu: „Szyfr to DHE-RSA-AES256-SHA, klucz publiczny serwera to 2048 bitów”. I 2048> 1024 :-).
sleske
@sleske: niezupełnie. Server public key (size)był i jest kluczem w cert. s_clientw 2011 roku w ogóle nie pokazał efemerycznego klucza; 1.0.2 w 2015 r. I Server Temp Keynowsze działa tak samo, jak kilka linii wyżej. Chociaż dobry serwer zwykle powinien mieć taki sam rozmiar DHE jak rozmiar uwierzytelniania RSA.
dave_thompson_085,

Odpowiedzi:

117

Problem tkwi w rozmiarze głównym. Maksymalny dopuszczalny rozmiar, jaki akceptuje Java, to 1024 bity. Jest to znany problem (zobacz JDK-6521495 ).

Raport o błędzie, że związana wspomina obejścia przy użyciu wdrażania BouncyCastle za JCE. Mam nadzieję, że to powinno Ci pomóc.

AKTUALIZACJA

Zostało to zgłoszone jako błąd JDK-7044060 i niedawno naprawione.

Należy jednak pamiętać, że limit został podniesiony tylko do 2048 bitów. W przypadku rozmiarów> 2048 bitów istnieje JDK-8072452 - Usuń maksymalny główny rozmiar kluczy DH ; wydaje się, że poprawka dotyczy 9.

Vivin Paliath
źródło
14
+1. Każdy, kto ma konto Sun Developer Network, zagłosuj na ten błąd.
Paŭlo Ebermann
1
Dzięki. Wydaje się to dość poważnym problemem, biorąc pod uwagę istnienie serwerów żądających większego rozmiaru! :( Próbowałem BouncyCastle; jeśli ustawisz go jako preferowanego dostawcę, zawiesza się z innym wyjątkiem (westchnienie) i nie widzę oczywistego sposobu użycia tego tylko dla DH. Jednak znalazłem alternatywne rozwiązanie, które znalazłem Dodam jako nową odpowiedź. (To nie jest ładne.)
sam
3
Chłodny. Zostało to naprawione w nowszych wersjach Java. Ale moje pytanie dotyczy korzystania ze starszej wersji .. Kiedy używam starszej wersji, czasami działa, a czasami daje powyższy wyjątek. Dlaczego tak przypadkowe zachowanie? Jeśli jest to błąd w Javie, to chyba nigdy nie powinien działać?
N ..
2
Poprawka 2048 została przeniesiona do IcedTea 2.5.3. Nowsze wersje IcedTea zwiększyły go do 4096.
fuzzyTew
1
Problemem jest rozmiar główny DH. Maksymalny dopuszczalny rozmiar, jaki akceptuje Java, to 2048 bitów. Podczas gdy czekamy, aż Oracle zwiększy limit, możesz skompilować z Excelsior Jet, który ma rozszerzony limit.
user1332994
67

Odpowiedź „Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files” nie zadziałała w moim przypadku, ale sugestia dostawcy JCE w BouncyCastle tak.

Oto kroki, które wykonałem, używając języka Java 1.6.0_65-b14-462 w systemie Mac OSC 10.7.5

1) Pobierz te słoiki:

2) przenieś te pliki jar do $ JAVA_HOME / lib / ext

3) Edytuj plik $ JAVA_HOME / lib / security / java.security w następujący sposób: security.provider.1 = org.bouncycastle.jce.provider.BouncyCastleProvider

uruchom ponownie aplikację przy użyciu środowiska JRE i spróbuj

mjj1409
źródło
5
pracuje dla mnie! choć nie do końca jestem pewien, co robię.
DiveInto
11
security.provider.2 = org.bouncycastle.jce.provider.BouncyCastleProvider działał lepiej, włożenie go na 1. spowodowało błędy w domyślnym oprogramowaniu.
TinusSky,
1
U mnie to też działa, ale dynamicznie dodałem dostawcę. Odnieś moją odpowiedź tutaj, aby uzyskać szczegółowe informacje.
przeciwko ladyniewowi
Wielkie dzięki, to zadziałało dla mnie i było wymagane do pomyślnego zbudowania źródła Tomcat 7.0.78.
phillipuniverse
@ mjj1409, w Javie 1.5 nie mamy ścieżki $ JAVA_HOME / lib / security
Mostafa
15

Oto moje rozwiązanie (java 1.6), również byłbym zainteresowany, dlaczego musiałem to zrobić:

Zauważyłem z javax.security.debug = ssl, że czasami używany zestaw szyfrów to TLS_DHE _..., a czasami jest to TLS_ECDHE _..... Później wydarzy się, gdy dodam BouncyCastle. Jeśli wybrano TLS_ECDHE_, PRZEZ WIĘKSZOŚĆ czasu działało, ale nie ZAWSZE, więc dodanie nawet dostawcy BouncyCastle było zawodne (nie powiodło się z tym samym błędem, mniej więcej co drugi raz). Wydaje mi się, że gdzieś w implementacji Sun SSL czasami wybiera DHE , a czasami ECDHE .

Dlatego rozwiązanie zamieszczone tutaj polega na całkowitym usunięciu szyfrów TLS_DHE_. UWAGA: BouncyCastle NIE jest wymagane do rozwiązania.

Utwórz więc plik certyfikacji serwera przez:

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

Zapisz to, ponieważ będzie przywoływane później, niż tutaj jest rozwiązanie dla SSL http get, z wyłączeniem zestawów szyfrowania 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));
        }

    }
}

Wreszcie, jak jest używany (certFilePath, jeśli ścieżka certyfikatu zapisanego z 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
źródło
9
Właśnie przetestowałem Twoje rozwiązanie. Działa zgodnie z przeznaczeniem. Dzięki. W rzeczywistości, po prostu dodając jdk.tls.disabledAlgorithms=DHE, ECDHEw JDK_HOME/jre/lib/security/java.securityrównież działa i uniknąć wszystkich ten kod.
Ludovic Guillaume
3
Wystarczy wyłączyć DHE pracował dla mnie jdk.tls.disabledAlgorithms=DHE. Używając 1.7.0_85-b15.
stephan f
1
Dodano jdk.tls.disabledAlgorithms = DHE, ECDHE w JDK_HOME / jre / lib / security / java.security i działało dobrze! Dziękuję Ci! Używając 1.7.0_79
Eric Na
1
Nie wyłączaj ECDHE. Różni się od DHE i nie używa nawet liczb pierwszych.
kubańczyk
1
Czy ktoś może mi powiedzieć, jak mogę uzyskać „certFilePath”. Utknąłem w tym przez tydzień. @Zsozso
user1172490
13

Powyższa odpowiedź jest poprawna, ale jeśli chodzi o obejście, miałem problemy z implementacją BouncyCastle, kiedy ustawiłem ją jako preferowanego dostawcę:

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

Jest to również omówione w jednym znalezionym wątku na forum, który nie wspomina o rozwiązaniu. http://www.javakb.com/Uwe/Forum.aspx/java-programmer/47512/TLS-problems

Znalazłem alternatywne rozwiązanie, które działa w moim przypadku, chociaż wcale nie jestem z niego zadowolony. Rozwiązaniem jest ustawienie go tak, aby algorytm Diffiego-Hellmana nie był w ogóle dostępny. Następnie, zakładając, że serwer obsługuje alternatywny algorytm, będzie wybierał podczas normalnej negocjacji. Oczywiście wadą tego rozwiązania jest to, że jeśli komuś uda się znaleźć serwer, który obsługuje tylko Diffie-Hellman przy 1024 bitach lub mniej, oznacza to, że nie będzie on działał tam, gdzie działał wcześniej.

Oto kod, który działa przy SSLSocket (przed połączeniem):

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()]));

Paskudny.

sam
źródło
1
Smutne, że to jedyny sposób :(. Ten bilet jest otwarty od 2007 roku. Dziwne, że nic nie zrobiono w tej sprawie od 4 lat.
Vivin Paliath
Jestem nowy w zabezpieczeniach Java. Proszę o pomoc, gdzie mam napisać ten fragment kodu?
Shashank
Wypróbowałem każde rozwiązanie w tym wątku i było to jedyne, które działało z moim ibm jvm (ibm-java-s390x-60).
Gianluca Greco
@Sam, jaka jest zmienna w ((SSLSocket) s)?
Mostafa
13

Możesz całkowicie wyłączyć DHE w swoim jdk, edytować jre / lib / security / java.security i upewnić się, że DHE jest wyłączone, np. lubić

jdk.tls.disabledAlgorithms=SSLv3, DHE.

Słup
źródło
4
który jest dostępny tylko w JDK 1.7 i nowszych. link
hoangthienan
Rozwiązałem problem za mnie JDK 1.8.0_144-b01
MrSmith42
12

Dostawcę można zainstalować dynamicznie:

1) Pobierz te słoiki:

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

2) Skopiuj słoiki do WEB-INF/lib(lub swoją ścieżkę klas)

3) Dodaj dostawcę dynamicznie:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

Security.addProvider(new BouncyCastleProvider());

angelcorral
źródło
To rozwiązanie działa dobrze i dobrze pasowało do mojego przypadku, ponieważ chciałem wprowadzić zmiany tylko na poziomie projektu, a nie na poziomie serwera / środowiska. Dzięki
ishanbakshi
Dzięki! to działało dla mnie. W moim przypadku to właśnie importowanie bcp 1.4 powodowało niepowodzenie wysyłania e-maili do Google.
Japheth Ongeri - inkalimeva
Otrzymuję javax.net.ssl.SSLHandshakeException: Unsupported curveId: 29 z wersją Java 1.6.0_27
inny koder
6

Jeśli używasz jdk1.7.0_04, zaktualizuj do jdk1.7.0_21. Problem został rozwiązany w tej aktualizacji.

Lekkie
źródło
2
Właśnie pobrałem Java SE Development Kit 7u25 i zgodnie z małym programem, który napisałem w celu określenia maksymalnego obsługiwanego rozmiaru DH , nadal jest to 1024.
user2666524
1
Nadal istnieje problem z JDK 1.7.0_25
Sébastien Vanmechelen
aktualizacja jre działała dla mnie. Miałem aktualizację 6.22 do wersji 7.59. problem rozwiązany.
Elazaron,
1
@Shashank - Uaktualnienie do JDK 1.8.0_73 zadziałało dla mnie.
dgoverde
DHKeyPairs o długościach bitowych większych niż 1024 wprowadzone z JDK 1.7.0_91, ale nie są dostępne publicznie.
Kolejny programista
6

Możliwe, że masz nieprawidłowe zależności Maven. Musisz znaleźć te biblioteki w hierarchii zależności Maven:

bcprov-jdk14, bcpkix-jdk14, bcmail-jdk14

Jeśli masz te zależności, to jest błąd i powinieneś to zrobić:

Dodaj zależność:

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

Wyklucz te zależności z artefaktu, który zawierał złe zależności, w moim przypadku jest to:

<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>
Jose Antonio Sánchez Pujante
źródło
Pytanie otrzymało już wiele odpowiedzi i ma jedną potwierdzoną odpowiedź. Co więcej, pytanie zostało zadane ponad 6 lat temu. Nie jestem pewien, czy nadal jest aktualny.
David Guyon
5

Spróbuj pobrać plik „Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files” z witryny pobierania oprogramowania Java i zamień pliki w środowisku JRE.

To zadziałało dla mnie i nie musiałem nawet używać BouncyCastle - standardowy Sun JCE był w stanie połączyć się z serwerem.

PS. Otrzymałem ten sam błąd (ArrayIndexOutOfBoundsException: 64), gdy próbowałem użyć BouncyCastle przed zmianą plików zasad, więc wygląda na to, że nasza sytuacja jest bardzo podobna.

mjomble
źródło
zrobiłeś coś jeszcze? czy po prostu skopiowałeś 2 pliki do folderu?
Joergi
Minęło trochę czasu, ale o ile pamiętam, to było wszystko, co musiałem zrobić. Oprócz ponownego ponownego uruchomienia wszelkich działających procesów Java.
mjomble
5

Jeśli nadal gryzie Cię ten problem ORAZ używasz Apache httpd v> 2.4.7, spróbuj tego: http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh

skopiowane z adresu URL :

Począwszy od wersji 2.4.7, mod_ssl będzie używać parametrów DH, które obejmują liczby pierwsze o długości większej niż 1024 bity. Jednak Java 7 i wcześniejsze ograniczają obsługę rozmiarów głównych DH do maksymalnie 1024 bitów.

Jeśli klient oparty na języku Java przerywa działanie z wyjątkami, takimi jak java.lang.RuntimeException: nie można wygenerować pary kluczy DH i java.security.InvalidAlgorithmParameterException: rozmiar główny musi być wielokrotnością 64 i może zawierać się tylko w zakresie od 512 do 1024 (włącznie), oraz httpd loguje błąd wewnętrzny alertu tlsv1 (numer alertu SSL 80) (na poziomie LogLevel lub wyższym), możesz zmienić kolejność listy szyfrów mod_ssl za pomocą SSLCipherSuite (prawdopodobnie w połączeniu z SSLHonorCipherOrder) lub użyć niestandardowych parametrów DH z 1024-bitową liczbą pierwszą , który zawsze będzie miał pierwszeństwo przed jakimikolwiek wbudowanymi parametrami DH.

Aby wygenerować niestandardowe parametry DH, użyj

openssl dhparam 1024

Komenda. Alternatywnie możesz użyć następujących standardowych parametrów 1024-bitowych DH z RFC 2409, sekcja 6.2:

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

Dodaj parametry niestandardowe, w tym wiersze „BEGIN DH PARAMETERS” i „END DH PARAMETERS”, na końcu pierwszego pliku certyfikatu skonfigurowanego za pomocą dyrektywy SSLCertificateFile.


Używam Java 1.6 po stronie klienta i to rozwiązało mój problem. Nie obniżyłem zestawów szyfrów ani podobnych, ale dodałem niestandardowy parametr DH do pliku certyfikatu.

pka
źródło
Należy pamiętać, że obecnie uważa się, że złamanie 1024-bitowego DH jest obliczeniowo wykonalne (choć piekielnie kosztowne).
plugwash
2

Mam ten sam problem z serwerem Yandex Maps, JDK 1.6 i Apache HttpClient 4.2.1. Błąd był

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

z włączonym debugowaniem, -Djavax.net.debug=all w dzienniku pojawił się komunikat

Could not generate DH keypair

Rozwiązałem ten problem, dodając bibliotekę BouncyCastle bcprov-jdk16-1.46.jari rejestrując dostawcę w klasie usług map

public class MapService {

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

    public GeocodeResult geocode() {

    }

}

Dostawca jest zarejestrowany przy pierwszym użyciu MapService.

v.ladynev
źródło
2

Napotkałem błąd SSL na serwerze CentOS z JDK 6.

Planowałem zainstalować nowszą wersję JDK (JDK 7), aby współistnieć z JDK 6, ale okazuje się, że samo zainstalowanie nowszego JDK z rpm -i nie wystarczyło.

Instalacja JDK 7 zakończy się powodzeniem tylko z rpm -U opcją aktualizacji, jak pokazano poniżej.

1. Pobierz 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. Instalacja RPM nie powiodła się

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. Aktualizacja RPM powiodła się

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. Potwierdź nową wersję

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)
Saheed
źródło
1

Rozwiązano problem, aktualizując do JDK 8.

anre
źródło
1

Używam coldfusion 8 na JDK 1.6.45 i miałem problemy z podaniem mi tylko czerwonych krzyżyków zamiast obrazów, a także z cfhttp nie mogącym połączyć się z lokalnym serwerem WWW przez ssl.

moim skryptem testowym do odtworzenia z coldfusion 8 był

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

spowodowało to dość ogólny błąd „Wyjątek we / wy: peer nie uwierzytelniony”. Następnie próbowałem dodać certyfikaty serwera, w tym certyfikaty główne i pośrednie, do magazynu kluczy java, a także do magazynu kluczy coldfusion, ale nic nie pomogło. następnie zdebugowałem problem z

java SSLPoke www.onlineumfragen.com 443

i dostał

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

i

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

Wtedy wpadłem na pomysł, że serwer WWW (w moim przypadku apache) ma bardzo nowoczesne szyfry dla ssl i jest dość restrykcyjny (ocena jakości a +) i używa silnych kluczy diffie hellmann z więcej niż 1024 bitami. oczywiście, coldfusion i java jdk 1.6.45 nie mogą sobie z tym poradzić. Następnym krokiem w odysee była myśl o zainstalowaniu alternatywnego dostawcy zabezpieczeń dla javy i zdecydowałem się na dmuchany zamek. zobacz także http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/

Następnie pobrałem

bcprov-ext-jdk15on-156.jar

z http://www.bouncycastle.org/latest_releases.html i zainstalowałem go pod C: \ jdk6_45 \ jre \ lib \ ext lub gdziekolwiek jest twój jdk, w oryginalnej instalacji coldfusion 8 znajdowałby się pod C: \ JRun4 \ jre \ lib \ ext, ale używam nowszego jdk (1.6.45) znajdującego się poza katalogiem coldfusion. bardzo ważne jest, aby umieścić bcprov-ext-jdk15on-156.jar w katalogu \ ext (kosztowało mnie to około dwie godziny i trochę włosów ;-), a potem wyedytowałem plik C: \ jdk6_45 \ jre \ lib \ security \ java.security (z wordpadem nie z editor.exe!) i umieść w jednej linii dla nowego dostawcy. potem lista wyglądała

#
# 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

(zobacz nowy w pozycji 1)

następnie całkowicie zrestartuj usługę coldfusion. możesz wtedy

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

i ciesz się tym uczuciem ... i oczywiście

co za noc i co za dzień. Miejmy nadzieję, że to pomoże (częściowo lub całkowicie) komuś tam. jeśli masz pytania, napisz do mnie na info ... (domena powyżej).

Raffael Meier
źródło
0

Jeśli serwer obsługuje szyfr, który nie zawiera DH, można zmusić klienta do wybrania tego szyfru i uniknąć błędu DH. Jak na przykład:

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

Pamiętaj, że określenie dokładnego szyfru jest podatne na złamanie w dłuższej perspektywie.

Jason Martin
źródło
0

Otrzymaliśmy ten sam dokładny błąd wyjątku, aby go naprawić po wielu godzinach przeglądania Internetu.

Pobraliśmy najwyższą wersję jdk, jaką mogliśmy znaleźć na oracle.com, zainstalowaliśmy ją i wskazaliśmy serwer aplikacji Jboss na katalog z zainstalowanym nowym jdk.

Ponownie uruchomiono Jboss, ponownie przetworzono, problem został rozwiązany !!!

Peter Azuka Molokwu
źródło
0

Mam ten błąd w Bamboo 5.7 + projekt Gradle + Apache. Gradle próbował uzyskać zależności z jednego z naszych serwerów za pośrednictwem protokołu SSL.

Rozwiązanie:

  1. Wygeneruj parametr DH:

z OpenSSL:

openssl dhparam 1024

przykładowe dane wyjściowe:

-----BEGIN DH PARAMETERS-----
MIGHfoGBALxpfMrDpImEuPlhopxYX4L2CFqQov+FomjKyHJrzj/EkTP0T3oAkjnS
oCGh6p07kwSLS8WCtYJn1GzItiZ05LoAzPs7T3ST2dWrEYFg/dldt+arifj6oWo+
vctDyDqIjlevUE+vyR9MF6B+Rfm4Zs8VGkxmsgXuz0gp/9lmftY7AgEC
-----END DH PARAMETERS-----
  1. Dołącz dane wyjściowe do pliku certyfikatu (dla Apache - SSLCertificateFileparam)

  2. Zrestartuj Apache

  3. Uruchom ponownie Bamboo

  4. Spróbuj ponownie zbudować projekt

Evgeny Lebedev
źródło
0

Kiedyś otrzymywałem podobny błąd podczas uzyskiwania dostępu do svn.apache.org z klientami Java SVN używającymi IBM JDK. Obecnie svn.apache.org użytkownicy korzystają z preferencji szyfrowania klientów.

Po uruchomieniu tylko raz z przechwytywaniem pakietów / javax.net.debug = ALL udało mi się umieścić na czarnej liście tylko jeden szyfr DHE i wszystko działa dla mnie (zamiast tego negocjowane jest ECDHE).

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

Dobra, szybka naprawa, gdy zmiana klienta nie jest łatwa.

covener
źródło
0

Ostatnio mam ten sam problem i po uaktualnieniu wersji jdk z wersji 1.6.0_45 do jdk1.7.0_191 co rozwiązało problem.

Sam
źródło
-1

U mnie następująca linia poleceń rozwiązała problem:

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

Używam JDK 1.7.0_79

rico-chango
źródło
1
Z taką samą sytuacją spotkałem się używając JDK 1.7.0_xx. BY domyślnie problem zostanie rozwiązany po użyciu jdk 1.8. Ale czasami nie możemy szybko zaktualizować jdk. Więc mój problem został rozwiązany po dodaniu konfiguracji systemu: System.setProperty ("https.protocols", "TLSv1.2"); System.setProperty ("deployment.security.TLSv1.2", "true");
Ramgau