Mengapa jabat tangan SSL memberikan pengecualian 'Tidak dapat menghasilkan DH keypair'?

142

Ketika saya membuat koneksi SSL dengan beberapa server IRC (tetapi tidak yang lain - mungkin karena metode enkripsi yang disukai server) saya mendapatkan pengecualian berikut:

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

Penyebab terakhir:

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

Contoh server yang menunjukkan masalah ini adalah aperture.esper.net:6697 (ini adalah server IRC). Contoh server yang tidak menunjukkan masalah adalah kornbluth.freenode.net:6697. [Tidak mengherankan, semua server di setiap jaringan berbagi perilaku masing-masing yang sama.]

Kode saya (yang seperti diketahui tidak berfungsi saat menghubungkan ke beberapa server SSL) adalah:

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

Ini startHandshake terakhir yang melempar pengecualian. Dan ya ada beberapa keajaiban yang terjadi dengan 'trustAllCerts'; kode itu memaksa sistem SSL untuk tidak memvalidasi sertifikat. (Jadi ... bukan masalah sertifikat.)

Jelas satu kemungkinan adalah bahwa server esper salah konfigurasi, tetapi saya mencari dan tidak menemukan referensi lain kepada orang-orang yang memiliki masalah dengan port SSL esper, dan 'openssl' menghubungkannya (lihat di bawah). Jadi saya bertanya-tanya apakah ini adalah batasan dukungan Java default SSL, atau sesuatu. Ada saran?

Inilah yang terjadi ketika saya terhubung ke aperture.esper.net 6697 menggunakan 'openssl' dari commandline:

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

Seperti yang disebutkan, setelah semua itu, itu berhasil terhubung yang lebih dari yang bisa Anda katakan untuk aplikasi Java saya.

Jika itu relevan, saya menggunakan OS X 10.6.8, Java versi 1.6.0_26.

sam
sumber
2
Alasannya tampaknya ini: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive). Tidak tahu ukuran apa yang dikirim oleh server di sini, dan apa spesifikasi mengatakan tentang ini.
Paŭlo Ebermann
@ PaŭloEbermann: Sebenarnya Anda dapat melihat ukuran server yang digunakan dalam openssloutput dalam pertanyaan: "Cipher adalah DHE-RSA-AES256-SHA, kunci publik Server adalah 2048 bit". Dan 2048> 1024 :-).
sleske
@sleske: tidak persis. Server public key (size)adalah, dan, adalah kunci dalam sertifikat tersebut. s_clientpada 2011 tidak menunjukkan kunci fana sama sekali; 1.0.2 di 2015 dan Server Temp Keylebih tinggi karena beberapa baris lebih tinggi. Meskipun server yang baik biasanya harus membuat ukuran DHE sama dengan ukuran RSA-auth.
dave_thompson_085

Jawaban:

117

Masalahnya adalah ukuran utama. Ukuran maksimum yang dapat diterima yang diterima Java adalah 1024 bit. Ini adalah masalah yang diketahui (lihat JDK-6521495 ).

Laporan bug yang saya tautkan dengan menyebutkan solusi menggunakan implementasi JCE BouncyCastle. Semoga itu bekerja untuk Anda.

MEMPERBARUI

Ini dilaporkan sebagai bug JDK-7044060 dan diperbaiki baru-baru ini.

Perhatikan, bagaimanapun, bahwa batas hanya dinaikkan menjadi 2048 bit. Untuk ukuran> 2048 bit, ada JDK-8072452 - Hapus ukuran utama maksimal DH Keys ; perbaikan tampaknya untuk 9.

Vivin Paliath
sumber
14
+1. Setiap orang yang memiliki Akun Jaringan Pengembang Sun, silakan pilih bug ini.
Paŭlo Ebermann
1
Terima kasih. Tampak masalah yang cukup serius mengingat keberadaan server yang meminta ukuran lebih besar! :( Saya mencoba BouncyCastle; jika Anda mengaturnya sebagai penyedia pilihan, crash dengan pengecualian yang berbeda (menghela napas), dan saya tidak dapat melihat cara yang jelas untuk menggunakannya hanya untuk DH. Namun, saya menemukan solusi alternatif, yang saya temukan akan ditambahkan sebagai jawaban baru. (Tidak cantik.)
sam
3
Keren. Ini telah diperbaiki di versi Java yang lebih baru. Tapi pertanyaan saya adalah tentang menggunakan versi yang lebih lama .. Ketika saya menggunakan versi yang lebih lama, kadang-kadang berfungsi dan kadang-kadang memberikan pengecualian di atas .. Mengapa perilaku begitu acak? Jika ini bug di java, maka saya kira itu seharusnya tidak pernah berhasil?
N ..
2
Perbaikan 2048 di-backport ke IcedTea 2.5.3.
IcedTea
1
Masalahnya adalah ukuran utama DH. Ukuran maksimum yang dapat diterima yang diterima Java adalah 2048 bit. Sementara kami menunggu Oracle untuk memperluas batas, Anda dapat mengkompilasi dengan Excelsior Jet yang memiliki batas diperluas.
user1332994
67

Jawaban "Java Cryptography Extension (JCE) File Kebijakan Yurisdiksi Kekuatan Tidak Terbatas" tidak berfungsi untuk saya tetapi saran penyedia JCE The BouncyCastle berhasil.

Berikut adalah langkah-langkah yang saya ambil menggunakan Java 1.6.0_65-b14-462 di Mac OSC 10.7.5

1) Unduh guci ini:

2) pindahkan guci ini ke $ JAVA_HOME / lib / ext

3) edit $ JAVA_HOME / lib / security / java.security sebagai berikut: security.provider.1 = org.bouncycastle.jce.provider.BouncyCastleProvider

restart aplikasi menggunakan JRE dan cobalah

mjj1409
sumber
5
bekerja untukku! meskipun tidak yakin apa yang saya lakukan.
DiveInto
11
security.provider.2 = org.bouncycastle.jce.provider.BouncyCastleProvider memang bekerja lebih baik, meletakkannya pada 1. mengakibatkan kesalahan pada perangkat lunak default.
TinusSky
1
Ini juga berfungsi untuk saya, tetapi saya telah menambahkan penyedia secara dinamis. Rujuk jawaban saya di sini untuk detailnya.
v.ladynev
Terima kasih banyak, ini bekerja untuk saya dan diperlukan untuk berhasil membangun sumber Tomcat 7.0.78.
phillipuniverse
@ mjj1409, di Jawa 1.5 kami tidak memiliki $ JAVA_HOME / lib / jalur keamanan
Mostafa
15

Inilah solusi saya (java 1.6), juga akan tertarik mengapa saya harus melakukan ini:

Saya perhatikan dari javax.security.debug = ssl, bahwa kadang-kadang suite cipher yang digunakan adalah TLS_DHE _... dan kadang-kadang itu adalah TLS_ECDHE _. Nanti akan terjadi jika saya menambahkan BouncyCastle. Jika TLS_ECDHE_ dipilih, PALING DARI waktu itu bekerja, tetapi tidak SELALU, jadi menambahkan bahkan penyedia BouncyCastle tidak dapat diandalkan (gagal dengan kesalahan yang sama, setiap kali atau lebih). Saya kira di suatu tempat di implementasi SSL Sun kadang-kadang memilih DHE , kadang-kadang memilih ECDHE .

Jadi solusi yang diposting di sini bergantung pada penghapusan cipher TLS_DHE_ sepenuhnya. CATATAN: BouncyCastle TIDAK diperlukan untuk solusi.

Jadi buat file sertifikasi server dengan:

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

Simpan ini karena akan direferensikan nanti, daripada di sini adalah solusi untuk mendapatkan http SSL, tidak termasuk suite cipher 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));
        }

    }
}

Akhirnya di sini adalah bagaimana ini digunakan (certFilePath jika jalur sertifikat disimpan dari 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
sumber
9
Baru saja menguji solusi Anda. Ini berfungsi sebagaimana dimaksud. Terima kasih. Sebenarnya, hanya menambahkan jdk.tls.disabledAlgorithms=DHE, ECDHEdalam JDK_HOME/jre/lib/security/java.securityjuga bekerja dan menghindari semua kode ini.
Ludovic Guillaume
3
Hanya menonaktifkan DHE bekerja untuk saya: jdk.tls.disabledAlgorithms=DHE. Menggunakan 1.7.0_85-b15.
stephan f
1
Menambahkan jdk.tls.disabledAlgorithms = DHE, ECDHE di JDK_HOME / jre / lib / security / java.security dan bekerja dengan baik! Terima kasih! Menggunakan 1.7.0_79
Eric Na
1
Jangan nonaktifkan ECDHE. Ini berbeda dari DHE dan bahkan tidak menggunakan bilangan prima.
kubanczyk
1
Dapatkah seseorang tolong beri tahu saya bagaimana saya bisa mendapatkan 'certFilePath'. Saya terjebak dalam hal ini selama seminggu. @Zsozso
user1172490
13

Jawaban di atas benar, tetapi dalam hal solusinya, saya punya masalah dengan implementasi BouncyCastle ketika saya menetapkannya sebagai penyedia pilihan:

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

Ini juga dibahas dalam satu utas forum yang saya temukan, yang tidak menyebutkan solusi. http://www.javakb.com/Uwe/Forum.aspx/java-programmer/47512/TLS-problems

Saya menemukan solusi alternatif yang berfungsi untuk kasus saya, meskipun saya sama sekali tidak senang dengan itu. Solusinya adalah mengaturnya sehingga algoritma Diffie-Hellman tidak tersedia sama sekali. Kemudian, seandainya server mendukung algoritma alternatif, itu akan memilih selama negosiasi normal. Jelas kelemahannya adalah jika seseorang entah bagaimana berhasil menemukan server yang hanya mendukung Diffie-Hellman pada 1024 bit atau kurang dari ini berarti ini tidak akan berfungsi di tempat yang dulu berfungsi sebelumnya.

Berikut adalah kode yang berfungsi diberikan SSLSocket (sebelum Anda menghubungkannya):

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

Menjijikan.

sam
sumber
1
Sedih karena ini adalah satu-satunya cara :(. Tiket itu telah dibuka sejak '07. Aneh bahwa tidak ada yang dilakukan tentang hal itu dalam 4 tahun.
Vivin Paliath
Saya baru mengenal sekuritas java. Tolong bantu di mana saya harus menulis kode ini?
Shashank
Saya mencoba setiap solusi di utas ini dan ini adalah satu-satunya yang bekerja dengan ibm jvm saya (ibm-java-s390x-60).
Gianluca Greco
@ Sam, Apa itu variabel dalam ((SSLSocket))?
Mostafa
13

Anda dapat menonaktifkan DHE sepenuhnya di jdk Anda, mengedit jre / lib / security / java.security dan memastikan DHE dinonaktifkan, mis. Suka

jdk.tls.disabledAlgorithms=SSLv3, DHE.

Tor
sumber
4
yang hanya tersedia di JDK 1.7 dan yang lebih baru. link
hoangthienan
Memecahkan masalah bagi saya JDK 1.8.0_144-b01
MrSmith42
12

Anda dapat menginstal penyedia secara dinamis:

1) Unduh guci ini:

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

2) Copy toples ke WEB-INF/lib(atau classpath Anda)

3) Tambahkan penyedia secara dinamis:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

Security.addProvider(new BouncyCastleProvider());

angelcorral
sumber
Solusi ini berfungsi dengan baik, dan sangat cocok untuk kasus saya karena saya ingin membuat perubahan hanya pada tingkat proyek dan tidak pada tingkat server / lingkungan. Terima kasih
ishanbakshi
Terima kasih! ini bekerja untuk saya. Dalam kasus saya itu adalah mengimpor bcp 1.4 yang menyebabkan email ke google gagal.
Japheth Ongeri - inkalimeva
Saya mendapatkan javax.net.ssl.SSLHandshakeException: Curve tidak didukungId: 29 dengan versi java 1.6.0_27
coder lain
6

Jika Anda menggunakan jdk1.7.0_04, tingkatkan ke jdk1.7.0_21. Masalah telah diperbaiki pada pembaruan itu.

Lekkie
sumber
2
Saya baru saja mengunduh Java SE Development Kit 7u25, dan menurut program kecil yang saya tulis untuk menentukan ukuran DH maksimum yang didukung , masih 1024.
user2666524
1
Masalah masih ada dengan JDK 1.7.0_25
Sébastien Vanmechelen
memperbarui jre bekerja untuk saya. sudah 6,22 diperbarui untuk 7,59. masalah terpecahkan.
Elazaron
1
@Shashank - Meningkatkan ke JDK 1.8.0_73 bekerja untuk saya.
dgoverde
DHKeyPairs dengan Panjang Bit Lebih Besar dari 1024 diperkenalkan dari JDK 1.7.0_91 tetapi tidak tersedia untuk umum.
Seorang programmer lain
6

Ada kemungkinan bahwa Anda memiliki dependensi Maven yang salah. Anda harus menemukan perpustakaan ini dalam hierarki ketergantungan Maven:

bcprov-jdk14, bcpkix-jdk14, bcmail-jdk14

Jika Anda memiliki dependensi ini yang merupakan kesalahan, dan Anda harus melakukan ini:

Tambahkan ketergantungan:

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

Kecualikan dependensi ini dari artefak yang menyertakan dependensi yang salah, dalam kasus saya itu adalah:

<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
sumber
Pertanyaan sudah menerima banyak jawaban dan memiliki satu jawaban yang divalidasi. Apalagi pertanyaannya sudah ditanyakan lebih dari 6 tahun yang lalu. Saya tidak yakin apakah itu masih relevan.
David Guyon
5

Coba unduh "Java Cryptography Extension (JCE) File Kebijakan Yurisdiksi Kekuatan Tidak Terbatas" dari situs unduhan Java dan ganti file dalam JRE Anda.

Ini bekerja untuk saya dan saya bahkan tidak perlu menggunakan BouncyCastle - standar Sun JCE dapat terhubung ke server.

PS. Saya mendapat kesalahan yang sama (ArrayIndexOutOfBoundsException: 64) ketika saya mencoba menggunakan BouncyCastle sebelum mengubah file kebijakan, jadi sepertinya situasi kami sangat mirip.

mjomble
sumber
Apakah kamu sudah melakukan hal lain? atau hanya menyalin 2 file ke folder?
Joergi
Sudah lama tapi sejauh yang saya ingat, hanya itu yang perlu saya lakukan. Selain memulai kembali proses Java yang berjalan sesudahnya.
mjomble
5

Jika Anda masih tergigit oleh masalah ini DAN Anda menggunakan Apache httpd v> 2.4.7, coba ini: http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh

disalin dari url :

Dimulai dengan versi 2.4.7, mod_ssl akan menggunakan parameter DH yang menyertakan bilangan prima dengan panjang lebih dari 1024 bit. Java 7 dan sebelumnya membatasi dukungan mereka untuk ukuran utama DH hingga maksimum 1024 bit.

Jika klien berbasis Java Anda membatalkan dengan pengecualian seperti java.lang.RuntimeException: Tidak dapat menghasilkan DH keypair dan java.security.InvalidAlgorithmParameterException: Ukuran prime harus lebih dari 64, dan hanya dapat berkisar dari 512 hingga 1024 (inklusif), dan httpd log kesalahan internal tlsv1 peringatan (nomor peringatan SSL 80) (pada info LogLevel atau lebih tinggi), Anda dapat mengatur ulang daftar kode mod_ssl dengan SSLCipherSuite (mungkin bersama dengan SSLHonorCipherOrder), atau Anda dapat menggunakan parameter DH khusus dengan prime 1024-bit , yang akan selalu didahulukan dari parameter DH bawaan.

Untuk menghasilkan parameter DH khusus, gunakan

openssl dhparam 1024

perintah. Atau, Anda dapat menggunakan parameter DH 1024-bit standar berikut dari RFC 2409, bagian 6.2:

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

Tambahkan parameter khusus termasuk baris "BEGIN DH PARAMETERS" dan "END DH PARAMETERS" ke akhir file sertifikat pertama yang telah Anda konfigurasikan menggunakan arahan SSLCertificateFile.


Saya menggunakan java 1.6 di sisi klien, dan itu memecahkan masalah saya. Saya tidak menurunkan cipher suites atau suka, tetapi menambahkan param DH yang dihasilkan kustom ke file cert ..

pka
sumber
Sadarilah bahwa sekarang diyakini bahwa DH 1024 bit layak secara komputasi (meskipun sangat mahal) untuk dihancurkan.
plugwash
2

Saya memiliki masalah yang sama dengan server Yandex Maps, JDK 1.6 dan Apache HttpClient 4.2.1. Kesalahannya adalah

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

dengan mengaktifkan debug oleh -Djavax.net.debug=all ada pesan di log

Could not generate DH keypair

Saya telah memperbaiki masalah ini dengan menambahkan perpustakaan BouncyCastle bcprov-jdk16-1.46.jardan mendaftarkan penyedia di kelas layanan peta

public class MapService {

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

    public GeocodeResult geocode() {

    }

}

Penyedia terdaftar pada penggunaan pertama MapService.

v.ladynev
sumber
2

Saya mengalami kesalahan SSL pada server CentOS yang menjalankan JDK 6.

Rencana saya adalah menginstal versi JDK yang lebih tinggi (JDK 7) untuk hidup berdampingan dengan JDK 6 tetapi ternyata hanya menginstal JDK yang lebih baru rpm -itidak cukup.

Instalasi JDK 7 hanya akan berhasil dengan rpm -Uopsi upgrade seperti yang diilustrasikan di bawah ini.

1. Unduh 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. Instalasi RPM gagal

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. Peningkatan RPM berhasil

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. Konfirmasikan versi baru

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)
Sahid
sumber
1

Memecahkan masalah dengan memutakhirkan ke JDK 8.

anre
sumber
1

Saya menggunakan coldfusion 8 pada JDK 1.6.45 dan memiliki masalah dengan memberi saya salib merah bukan gambar, dan juga dengan cfhttp tidak dapat terhubung ke server web lokal dengan ssl.

skrip pengujian saya untuk mereproduksi dengan coldfusion 8 adalah

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

ini memberi saya kesalahan yang cukup umum dari "Pengecualian I / O: rekan tidak diautentikasi." Saya kemudian mencoba menambahkan sertifikat server termasuk root dan sertifikat menengah ke keystore java dan juga keystore coldfusion, tetapi tidak ada yang membantu. lalu aku memperdebatkan masalah dengan

java SSLPoke www.onlineumfragen.com 443

dan mendapatkan

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

dan

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

Saya kemudian memiliki gagasan bahwa server web (apache dalam kasus saya) memiliki cipher yang sangat modern untuk ssl dan cukup ketat (memenuhi nilai +) dan menggunakan kunci hellmann diffie yang kuat dengan lebih dari 1024 bit. jelas, coldfusion dan java jdk 1.6.45 tidak bisa mengelola ini. Langkah selanjutnya dalam odysee adalah memikirkan menginstal penyedia keamanan alternatif untuk java, dan saya memutuskan untuk goyang istana. lihat juga http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-in-in-netbeans-or-eclipse-for-java-jse-projects/

Saya kemudian mengunduh

bcprov-ext-jdk15on-156.jar

dari http://www.bouncycastle.org/latest_releases.html dan menginstalnya di bawah C: \ jdk6_45 \ jre \ lib \ ext atau di mana pun jdk Anda berada, dalam instalasi asli coldfusion 8 itu akan berada di bawah C: \ JRun4 \ jre \ lib \ ext tetapi saya menggunakan jdk yang lebih baru (1.6.45) yang terletak di luar direktori coldfusion. sangat penting untuk meletakkan bcprov-ext-jdk15on-156.jar di direktori \ ext (ini biayanya sekitar dua jam dan sedikit rambut ;-) lalu saya edit file C: \ jdk6_45 \ jre \ lib \ security \ java.security (dengan wordpad tidak dengan editor.exe!) dan dimasukkan ke dalam satu baris untuk penyedia baru. setelah itu daftar tampak seperti

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

(lihat yang baru di posisi 1)

kemudian restart layanan coldfusion sepenuhnya. kamu bisa kemudian

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

dan nikmati perasaan ... dan tentu saja

malam yang indah dan hari yang indah. Semoga ini akan membantu (sebagian atau sepenuhnya) kepada seseorang di luar sana. jika Anda memiliki pertanyaan, cukup kirimkan saya di info ... (domain di atas).

Raffael Meier
sumber
0

Jika server mendukung cipher yang tidak termasuk DH, Anda dapat memaksa klien untuk memilih cipher itu dan menghindari kesalahan DH. Seperti:

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

Perlu diingat bahwa menentukan sandi yang tepat cenderung rusak dalam jangka panjang.

Jason Martin
sumber
0

Kami mendapat kesalahan pengecualian yang sama persis dikembalikan, untuk memperbaikinya setelah berjam-jam menjelajahi internet.

Kami mengunduh versi jdk tertinggi yang dapat kami temukan di oracle.com, menginstalnya dan mengarahkan server aplikasi Jboss ke direktori jdk baru yang diinstal.

Restart Jboss, diproses ulang, problemo diperbaiki !!!

Peter Azuka Molokwu
sumber
0

Saya mendapatkan kesalahan ini dengan Bamboo 5.7 + proyek Gradle + Apache. Gradle mencoba mendapatkan beberapa dependensi dari salah satu server kami melalui SSL.

Larutan:

  1. Hasilkan Param Param:

dengan OpenSSL:

openssl dhparam 1024

contoh output:

-----BEGIN DH PARAMETERS-----
MIGHfoGBALxpfMrDpImEuPlhopxYX4L2CFqQov+FomjKyHJrzj/EkTP0T3oAkjnS
oCGh6p07kwSLS8WCtYJn1GzItiZ05LoAzPs7T3ST2dWrEYFg/dldt+arifj6oWo+
vctDyDqIjlevUE+vyR9MF6B+Rfm4Zs8VGkxmsgXuz0gp/9lmftY7AgEC
-----END DH PARAMETERS-----
  1. Tambahkan output ke file sertifikat (untuk Apache - SSLCertificateFileparam)

  2. Mulai ulang apache

  3. Mulai ulang bambu

  4. Cobalah untuk membangun proyek lagi

Evgeny Lebedev
sumber
0

Saya digunakan untuk mendapatkan kesalahan serupa mengakses svn.apache.org dengan klien java SVN menggunakan IBM JDK. Saat ini, svn.apache.org pengguna preferensi cipher klien.

Setelah berjalan sekali saja dengan paket capture / javax.net.debug = SEMUA Saya bisa daftar hitam hanya satu cipher DHE dan hal-hal bekerja untuk saya (ECDHE malah dinegosiasikan sebagai gantinya).

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

Perbaikan cepat yang bagus ketika tidak mudah untuk mengubah klien.

covener
sumber
0

Baru-baru ini saya memiliki masalah yang sama dan setelah memutakhirkan versi jdk dari 1.6.0_45 ke jdk1.7.0_191 yang menyelesaikan masalah.

Sam
sumber
-1

Bagi saya, baris perintah berikut memperbaiki masalah ini:

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

Saya menggunakan JDK 1.7.0_79

rico-chango
sumber
1
Saya menghadapi situasi yang sama menggunakan JDK 1.7.0_xx. DENGAN masalah default akan diselesaikan setelah menggunakan jdk 1.8. Tetapi kadang-kadang kita tidak dapat memutakhirkan jdk dengan cepat. Jadi masalah saya terpecahkan setelah menambahkan konfigurasi sistem: System.setProperty ("https.protocols", "TLSv1.2"); System.setProperty ("deployment.security.TLSv1.2", "true");
Ramgau