Tại sao bắt tay SSL lại đưa ra 'Không thể tạo ngoại lệ khóa DH'?


142

Khi tôi thực hiện kết nối SSL với một số máy chủ IRC (nhưng không phải các máy chủ khác - có lẽ là do phương thức mã hóa ưa thích của máy chủ), tôi gặp ngoại lệ sau:

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

Nguyên nhân cuối cùng:

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

Một ví dụ về máy chủ thể hiện vấn đề này là aperture.esper.net:6697 (đây là máy chủ IRC). Một ví dụ về máy chủ không thể hiện vấn đề là kornbluth.freenode.net:6697. [Không ngạc nhiên, tất cả các máy chủ trên mỗi mạng đều có chung hành vi tương ứng.]

Mã của tôi (như đã lưu ý không hoạt động khi kết nối với một số máy chủ SSL) là:

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

Đó là sự khởi đầu cuối cùng. Bắt đầu ném ngoại lệ. Và vâng, có một số phép thuật đang diễn ra với 'Trust ALLCerts'; mã đó buộc hệ thống SSL không xác nhận certs. (Vì vậy ... không phải là vấn đề chứng chỉ.)

Rõ ràng một khả năng là máy chủ của esper bị định cấu hình sai, nhưng tôi đã tìm kiếm và không tìm thấy bất kỳ tài liệu tham khảo nào khác cho những người gặp vấn đề với các cổng SSL của esper và 'openssl' kết nối với nó (xem bên dưới). Vì vậy, tôi tự hỏi liệu đây có phải là một hạn chế của hỗ trợ SSL mặc định của Java hay không. Bất kỳ đề xuất?

Đây là những gì xảy ra khi tôi kết nối với aperture.esper.net 6697 bằng cách sử dụng 'openssl' từ dòng lệnh:

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

Như đã lưu ý, sau tất cả những điều đó, nó kết nối thành công, nhiều hơn những gì bạn có thể nói cho ứng dụng Java của tôi.

Nếu nó có liên quan, tôi đang sử dụng OS X 10.6.8, phiên bản Java 1.6.0_26.


2
Lý do có vẻ là thế này : Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive). Không biết kích thước nào được gửi bởi máy chủ ở đây và thông số kỹ thuật nói gì về điều này.
Paŭlo Ebermann

@ PaŭloEbermann: Trên thực tế, bạn có thể thấy kích thước máy chủ được sử dụng trong opensslđầu ra trong câu hỏi: "Mật mã là DHE-RSA-AES256-SHA, Khóa công khai của máy chủ là 2048 bit". Và 2048> 1024 :-).
sleske

@sleske: không chính xác. Server public key (size)đã, và là, chìa khóa trong chứng chỉ. s_clientnăm 2011 không hiển thị khóa phù du nào cả; 1.0.2 trong năm 2015 trở lên làm Server Temp Keymột số dòng cao hơn. Mặc dù một máy chủ tốt thường nên tạo kích thước DHE giống như kích thước RSA-auth.
dave_thndry_085

Câu trả lời:


117

Vấn đề là kích thước nguyên tố. Kích thước tối đa có thể chấp nhận mà Java chấp nhận là 1024 bit. Đây là một vấn đề đã biết (xem JDK-6521495 ).

Báo cáo lỗi mà tôi đã liên kết để đề cập đến một cách giải quyết bằng cách sử dụng triển khai JCE của BouncyCastle. Hy vọng rằng sẽ làm việc cho bạn.

CẬP NHẬT

Điều này đã được báo cáo là lỗi JDK-7044060 và đã được sửa gần đây.

Lưu ý, tuy nhiên, giới hạn chỉ được nâng lên 2048 bit. Đối với kích thước> 2048 bit, có JDK-8072452 - Loại bỏ kích thước nguyên tố tối đa của Khóa DH ; sửa chữa dường như là cho 9.


14
+1. Mọi người có Tài khoản Mạng của Nhà phát triển Mặt trời, vui lòng bỏ phiếu cho lỗi này.
Paŭlo Ebermann

1
Cảm ơn. Có vẻ như một vấn đề khá nghiêm trọng do sự tồn tại của các máy chủ yêu cầu kích thước lớn hơn! :( Tôi đã dùng thử BouncyCastle, nếu bạn thiết lập nó là nhà cung cấp ưu tiên thì nó gặp sự cố với một ngoại lệ khác (thở dài) và tôi không thể thấy một cách rõ ràng để sử dụng chỉ cho DH. Tuy nhiên, tôi đã tìm thấy một giải pháp thay thế 'sẽ thêm vào như một câu trả lời mới. (Nó không đẹp lắm.)
sam

3
Mát mẻ. Điều này đã được sửa trong các phiên bản mới hơn của Java. Nhưng câu hỏi của tôi là về việc sử dụng phiên bản cũ hơn .. Khi tôi sử dụng phiên bản cũ hơn, đôi khi nó hoạt động và đôi khi nó đưa ra ngoại lệ ở trên..Tại sao hành vi ngẫu nhiên như vậy? Nếu đó là một lỗi trong java, thì tôi đoán nó không bao giờ nên hoạt động?
N ..

2
Bản sửa lỗi 2048 đã được nhập vào IcedTea 2.5.3. Các phiên bản mới hơn của IcedTea đã tăng lên 4096.
fuzzyTew

1
Vấn đề là kích thước nguyên tố DH. Kích thước tối đa chấp nhận được mà Java chấp nhận là 2048 bit. Trong khi chúng tôi chờ đợi Oracle mở rộng giới hạn, bạn có thể biên dịch với Excelsior Jet có giới hạn mở rộng.
dùng1332994

67

Câu trả lời "Tệp chính sách thẩm quyền sức mạnh không giới hạn mã hóa Java (JCE)" không hoạt động đối với tôi nhưng đề xuất nhà cung cấp JCE của BouncyCastle đã làm.

Dưới đây là các bước tôi đã thực hiện bằng Java 1.6.0_65-b14-462 trên Mac OSC 10.7.5

1) Tải về các lọ này:

2) di chuyển các lọ này sang $ JAVA_HOME / lib / ext

3) chỉnh sửa $ JAVA_HOME / lib / security / java.security như sau: security.provider.1 = org.bouncycastle.jce.provider.BouncyCastleProvider

khởi động lại ứng dụng bằng JRE và dùng thử


5
làm việc cho tôi mặc dù không chắc chắn những gì tôi đang làm
DiveInto

11
security.provider.2 = org.bouncycastle.jce.provider.BouncyCastleProvider đã hoạt động tốt hơn, đưa nó vào 1. dẫn đến lỗi trong phần mềm mặc định.
TinusSky 7/07/2015

1
Điều này cũng làm việc cho tôi, nhưng tôi đã thêm một nhà cung cấp năng động. Giới thiệu câu trả lời của tôi ở đây để biết chi tiết.
v.ladynev

Cảm ơn rất nhiều, điều này đã làm việc cho tôi và được yêu cầu để xây dựng thành công nguồn Tomcat 7.0.78.
phillipuniverse

@ mjj1409, trong Java 1.5, chúng tôi không có đường dẫn $ JAVA_HOME / lib / bảo mật
Mostafa

15

Đây là giải pháp của tôi (java 1.6), cũng sẽ quan tâm tại sao tôi phải làm điều này:

Tôi nhận thấy từ javax.security.debug = ssl, đôi khi bộ mật mã được sử dụng là TLS_DHE _... và đôi khi đó là TLS_ECDHE _.... Điều sau này sẽ xảy ra nếu tôi thêm BouncyCastle. Nếu TLS_ECDHE_ được chọn, MOST OF thời gian nó hoạt động, nhưng không LUÔN, do đó, việc thêm ngay cả nhà cung cấp BouncyCastle cũng không đáng tin cậy (thất bại với cùng một lỗi, mọi lúc hoặc lâu hơn). Tôi đoán ở đâu đó trong triển khai Sun SSL đôi khi nó chọn DHE , đôi khi nó chọn ECDHE .

Vì vậy, giải pháp được đăng ở đây phụ thuộc vào việc loại bỏ hoàn toàn mật mã TLS_DHE_. LƯU Ý: BouncyCastle KHÔNG cần thiết cho giải pháp.

Vì vậy, tạo tập tin chứng nhận máy chủ bằng cách:

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

Lưu cái này vì nó sẽ được tham chiếu sau, hơn đây là giải pháp cho SSL http get, ngoại trừ bộ mật mã 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));
        }

    }
}

Cuối cùng, đây là cách nó được sử dụng (certFilePath nếu đường dẫn của chứng chỉ được lưu từ 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();
        }

9
Chỉ cần thử nghiệm giải pháp của bạn. Nó hoạt động như dự định. Cảm ơn. Trên thực tế, chỉ cần thêm jdk.tls.disabledAlgorithms=DHE, ECDHEvào JDK_HOME/jre/lib/security/java.securitycũng hoạt động và tránh tất cả các mã này.
Ludovic Guillaume

3
Chỉ cần vô hiệu hóa DHE làm việc cho tôi : jdk.tls.disabledAlgorithms=DHE. Sử dụng 1.7.0_85-b15.
stephan f

1
Đã thêm jdk.tls.disablesAlologistsms = DHE, ECDHE trong JDK_HOME / jre / lib / security / java.security và hoạt động tốt! Cảm ơn bạn! Sử dụng 1.7.0_79
Eric Na

1
Đừng vô hiệu hóa ECDHE. Nó khác với DHE và thậm chí không sử dụng số nguyên tố.
kubanchot

1
Ai đó có thể vui lòng cho tôi biết làm thế nào tôi có thể nhận được 'certFilePath'. Tôi đã bị mắc kẹt trong điều này trong một tuần. @Zsozso
1172490

13

Câu trả lời ở trên là chính xác, nhưng về mặt giải pháp, tôi gặp vấn đề với việc triển khai BouncyCastle khi tôi đặt nó làm nhà cung cấp ưa thích:

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

Điều này cũng được thảo luận trong một chủ đề diễn đàn mà tôi tìm thấy, không đề cập đến một giải pháp. http://www.javakb.com/Uwe/Forum.aspx/java-programmer/48512/TLS-probols

Tôi đã tìm thấy một giải pháp thay thế phù hợp với trường hợp của mình, mặc dù tôi hoàn toàn không hài lòng với nó. Giải pháp là đặt nó sao cho thuật toán Diffie-Hellman hoàn toàn không có. Sau đó, giả sử máy chủ hỗ trợ một thuật toán thay thế, nó sẽ được chọn trong quá trình đàm phán thông thường. Rõ ràng nhược điểm của điều này là nếu ai đó bằng cách nào đó quản lý để tìm một máy chủ chỉ hỗ trợ Diffie-Hellman ở mức 1024 bit trở xuống thì điều này thực sự có nghĩa là nó sẽ không hoạt động ở nơi trước đây nó hoạt động.

Đây là mã hoạt động được cung cấp SSLSocket (trước khi bạn kết nối nó):

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

Bẩn thỉu.


1
Đáng buồn là đây là cách duy nhất :(. Chiếc vé đó đã được mở từ '07. Điều kỳ lạ là không có gì được thực hiện trong 4 năm.
Vivin Paliath

Tôi chưa quen với chứng khoán java. Xin hãy giúp tôi nên viết đoạn mã này ở đâu?
Shashank

Tôi đã thử mọi giải pháp trong chủ đề này và đây là giải pháp duy nhất hoạt động với ibm jvm của tôi (ibm-java-s390x-60).
Gianluca Greco

@Sam, biến nào trong ((SSLSocket) s)?
Mostafa

13

Bạn có thể vô hiệu hóa hoàn toàn DHE trong jdk của mình, chỉnh sửa jre / lib / security / java.security và đảm bảo DHE bị vô hiệu hóa, vd. giống

jdk.tls.disabledAlgorithms=SSLv3, DHE.


4
chỉ có sẵn trong JDK 1.7 trở lên. liên kết
hoangthienan

Đã giải quyết vấn đề cho tôi JDK 1.8.0_144-b01
MrSmith42

12

Bạn có thể cài đặt nhà cung cấp một cách linh hoạt:

1) Tải về các lọ này:

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

2) Sao chép lọ vào WEB-INF/lib(hoặc đường dẫn của bạn)

3) Thêm nhà cung cấp động:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

Security.addProvider(new BouncyCastleProvider());


Giải pháp này hoạt động tốt và phù hợp với trường hợp của tôi vì tôi chỉ muốn thực hiện các thay đổi ở cấp dự án chứ không phải ở cấp máy chủ / môi trường. Cảm ơn
ishanbakshi

Cảm ơn! Điều này làm việc cho tôi. Trong trường hợp của tôi, đó là việc nhập bcp 1.4 khiến cho email bị lỗi.
Japheth Ongeri - inkalimeva

Tôi đang nhận javax.net.ssl.SSLHandshakeException: Đường cong không được hỗ trợId: 29 với phiên bản java 1.6.0_27
Một lập trình viên khác


6

Nếu bạn đang sử dụng jdk1.7.0_04, hãy nâng cấp lên jdk1.7.0_21. Vấn đề đã được khắc phục trong bản cập nhật đó.


2
Tôi vừa tải xuống Bộ công cụ phát triển Java SE 7u25 và theo chương trình nhỏ mà tôi đã viết để xác định kích thước DH được hỗ trợ tối đa , nó vẫn là 1024.
user2666524

1
Vấn đề vẫn còn tồn tại với JDK 1.7.0_25
Sébastien Vanmechelen

cập nhật jre làm việc cho tôi. đã có 6.22 cập nhật lên 7.59. Vấn đề được giải quyết.
Elazaron

1
@Shashank - Nâng cấp lên JDK 1.8.0_73 làm việc cho tôi.
dgoverde 17/2/2016

DHKeyPairs với độ dài bit lớn hơn 1024 được giới thiệu từ JDK 1.7.0_91 nhưng không có sẵn công khai.
Một lập trình viên khác

6

Có thể bạn có phụ thuộc Maven không chính xác. Bạn phải tìm các thư viện này trong hệ thống phân cấp phụ thuộc Maven:

bcprov-jdk14, bcpkix-jdk14, bcmail-jdk14

Nếu bạn có những phụ thuộc đó là lỗi và bạn nên làm điều này:

Thêm phụ thuộc:

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

Loại trừ các phụ thuộc này khỏi tạo phẩm bao gồm các phụ thuộc sai, trong trường hợp của tôi, đó là:

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

Câu hỏi đã nhận được nhiều câu trả lời và có một câu trả lời xác thực. Hơn nữa, câu hỏi đã được hỏi hơn 6 năm trước. Tôi không chắc nếu nó vẫn còn liên quan.
David Guyon

5

Hãy thử tải xuống "Tệp chính sách quyền lực mở rộng mã hóa Java (JCE) không giới hạn" từ trang tải xuống Java và thay thế các tệp trong JRE của bạn.

Điều này làm việc cho tôi và tôi thậm chí không cần sử dụng BouncyCastle - Sun JCE tiêu chuẩn có thể kết nối với máy chủ.

Tái bút Tôi đã gặp lỗi tương tự (ArrayIndexOutOfBoundException: 64) khi tôi đã thử sử dụng BouncyCastle trước khi thay đổi các tệp chính sách, vì vậy có vẻ như tình huống của chúng tôi rất giống nhau.


bạn đã làm gì khác chưa? hoặc chỉ sao chép 2 tập tin vào thư mục?
Joergi

Đã được một thời gian nhưng theo tôi nhớ, đó là tất cả những gì tôi cần làm. Ngoài việc khởi động lại bất kỳ quy trình Java đang chạy nào sau đó.
mjomble

5

Nếu bạn vẫn bị vấn đề này cắn bạn đang sử dụng Apache httpd v> 2.4.7, hãy thử điều này: http://httpd.apache.org/docs/cản/ssl/ssl_faq.html#javadh

sao chép từ url :

Bắt đầu với phiên bản 2.4.7, mod_ssl sẽ sử dụng các tham số DH bao gồm các số nguyên tố có độ dài hơn 1024 bit. Tuy nhiên, Java 7 và trước đó giới hạn sự hỗ trợ của họ đối với các kích thước nguyên tố DH tối đa là 1024 bit.

Nếu ứng dụng khách dựa trên Java của bạn hủy bỏ các ngoại lệ, chẳng hạn như java.lang.R nbException: Không thể tạo khóa DH và java.security.InvalidAlerskymParameterException: Kích thước Prime phải là bội số của 64 và chỉ có thể nằm trong khoảng từ 512 đến 1024 (bao gồm) và httpd ghi lại lỗi nội bộ cảnh báo tlsv1 (cảnh báo SSL số 80) (tại thông tin LogLevel hoặc cao hơn), bạn có thể sắp xếp lại danh sách mật mã của mod_ssl với SSLCodesSuite (có thể kết hợp với SSLHonorCodesOrder) hoặc bạn có thể sử dụng các tham số DH tùy chỉnh với số nguyên tố 1024 bit , sẽ luôn được ưu tiên hơn bất kỳ tham số DH tích hợp nào.

Để tạo tham số DH tùy chỉnh, sử dụng

openssl dhparam 1024

chỉ huy. Ngoài ra, bạn có thể sử dụng các tham số DH tiêu chuẩn 1024 bit sau từ RFC 2409, phần 6.2:

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

Thêm các tham số tùy chỉnh bao gồm các dòng "BEGIN DH PARAMETERS" và "END DH PARAMETERS" vào cuối tệp chứng chỉ đầu tiên bạn đã định cấu hình bằng lệnh SSLCertertFile.


Tôi đang sử dụng java 1.6 ở phía máy khách và nó đã giải quyết được vấn đề của tôi. Tôi đã không hạ thấp bộ mật mã hoặc thích, nhưng đã thêm một tham số DH được tạo tùy chỉnh vào tệp cert ..


Xin lưu ý rằng hiện tại người ta tin rằng 1024 bit DH là khả thi về mặt tính toán (mặc dù rất đắt) để phá vỡ.
cắm vào

2

Tôi gặp vấn đề tương tự với máy chủ Yandex Maps, JDK 1.6 và Apache HttpClient 4.2.1. Lỗi là

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

với gỡ lỗi được kích hoạt bởi -Djavax.net.debug=all có một thông báo trong nhật ký

Could not generate DH keypair

Tôi đã khắc phục vấn đề này bằng cách thêm thư viện BouncyCastle bcprov-jdk16-1.46.jarvà đăng ký nhà cung cấp trong lớp dịch vụ bản đồ

public class MapService {

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

    public GeocodeResult geocode() {

    }

}

Một nhà cung cấp được đăng ký tại lần sử dụng đầu tiên MapService.


2

Tôi đã gặp lỗi SSL trên máy chủ CentOS chạy JDK 6.

Kế hoạch của tôi là cài đặt phiên bản JDK cao hơn (JDK 7) để cùng tồn tại với JDK 6 nhưng hóa ra chỉ đơn thuần là cài đặt JDK mới hơn với rpm -i là không đủ.

Cài đặt JDK 7 sẽ chỉ thành công với rpm -U tùy chọn nâng cấp như minh họa bên dưới.

1. Tải xuống 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. Cài đặt RPM không thành công

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. Nâng cấp RPM thành công

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. Xác nhận phiên bản mới

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

Giải quyết vấn đề bằng cách nâng cấp lên JDK 8.


1

Tôi sử dụng Coldfusion 8 trên JDK 1.6.45 và gặp vấn đề với việc chỉ cho tôi chữ thập đỏ thay vì hình ảnh và với cfhttp không thể kết nối với máy chủ web cục bộ bằng ssl.

kịch bản thử nghiệm của tôi để sao chép với Coldfusion 8 là

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

điều này mang lại cho tôi lỗi khá chung chung của "Ngoại lệ I / O: ngang hàng không được xác thực." Sau đó, tôi đã cố gắng thêm chứng chỉ của máy chủ bao gồm chứng chỉ gốc và chứng chỉ trung gian vào kho khóa java và cả kho khóa khóa Coldfusion, nhưng không có gì giúp được. sau đó tôi gỡ lỗi với

java SSLPoke www.onlineumfragen.com 443

và có

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

Sau đó, tôi đã có ý tưởng rằng máy chủ web (apache trong trường hợp của tôi) có mật mã rất hiện đại cho ssl và khá hạn chế (điểm số a +) và sử dụng các khóa hellmann diffie mạnh với hơn 1024 bit. rõ ràng, Coldfusion và java jdk 1.6.45 không thể quản lý điều này. Bước tiếp theo trong odysee là nghĩ đến việc cài đặt một nhà cung cấp bảo mật thay thế cho java và tôi đã quyết định cho lâu đài bouncy. xem thêm http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/

Sau đó tôi đã tải xuống

bcprov-ext-jdk15on-156.jar

từ http : //www jre \ lib \ ext nhưng tôi sử dụng jdk mới hơn (1.6.45) nằm bên ngoài thư mục Coldfusion. điều rất quan trọng là đặt bcprov-ext-jdk15on-156.jar trong thư mục \ ext (điều này làm tôi mất khoảng hai giờ và một số tóc ;-) sau đó tôi đã chỉnh sửa tệp C: \ jdk6_45 \ jre \ lib \ security \ java.security (với wordpad không phải với Editor.exe!) và đặt một dòng cho nhà cung cấp mới. sau đó danh sách trông giống như

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

(xem cái mới ở vị trí 1)

sau đó khởi động lại dịch vụ Coldfusion hoàn toàn. sau đó bạn có thể

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

và tận hưởng cảm giác ... và tất nhiên

Thật là một đêm và những gì một ngày. Hy vọng rằng điều này sẽ giúp (một phần hoặc toàn bộ) cho một ai đó ngoài kia. nếu bạn có thắc mắc, chỉ cần gửi thư cho tôi tại thông tin ... (tên miền ở trên).


0

Nếu máy chủ hỗ trợ một mật mã không bao gồm DH, bạn có thể buộc khách hàng chọn mật mã đó và tránh lỗi DH. Nhu la:

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

Hãy nhớ rằng việc chỉ định một mật mã chính xác dễ bị hỏng trong thời gian dài.


0

Chúng tôi đã nhận được lỗi ngoại lệ chính xác tương tự được trả lại, để khắc phục nó thật dễ dàng sau nhiều giờ lướt internet.

Chúng tôi đã tải xuống phiên bản cao nhất của jdk mà chúng tôi có thể tìm thấy trên oracle.com, cài đặt nó và chỉ máy chủ ứng dụng Jboss vào thư mục của jdk mới được cài đặt.

Đã khởi động lại Jboss, đã xử lý lại, đã sửa lỗi !!!


0

Tôi đã gặp lỗi này với dự án Grad 5.7 + + Apache. Gradle đã cố gắng để có được một số phụ thuộc từ một trong các máy chủ của chúng tôi thông qua SSL.

Giải pháp:

  1. Tạo thông số DH:

với OpenSSL:

openssl dhparam 1024

đầu ra ví dụ:

-----BEGIN DH PARAMETERS-----
MIGHfoGBALxpfMrDpImEuPlhopxYX4L2CFqQov+FomjKyHJrzj/EkTP0T3oAkjnS
oCGh6p07kwSLS8WCtYJn1GzItiZ05LoAzPs7T3ST2dWrEYFg/dldt+arifj6oWo+
vctDyDqIjlevUE+vyR9MF6B+Rfm4Zs8VGkxmsgXuz0gp/9lmftY7AgEC
-----END DH PARAMETERS-----
  1. Nối đầu ra vào tệp chứng chỉ (đối với Apache - SSLCertificateFileparam)

  2. Khởi động lại apache

  3. Khởi động lại tre

  4. Cố gắng xây dựng lại dự án


0

Tôi đã từng gặp một lỗi tương tự khi truy cập svn.apache.org với các máy khách java SVN bằng cách sử dụng IBM JDK. Hiện tại, svn.apache.org sử dụng tùy chọn mật mã của khách hàng.

Sau khi chạy chỉ một lần với gói chụp / javax.net.debug = TẤT CẢ tôi đã có thể đưa vào danh sách đen chỉ một mật mã DHE duy nhất và mọi thứ hoạt động với tôi (thay vào đó, ECDHE được đàm phán).

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

Một sửa chữa nhanh chóng tốt đẹp khi không dễ dàng để thay đổi khách hàng.


0

Gần đây tôi có cùng một vấn đề và sau khi nâng cấp phiên bản jdk từ 1.6.0_45 lên jdk1.7.0_191 đã giải quyết vấn đề.


-1

Đối với tôi, dòng lệnh sau đã khắc phục sự cố:

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

Tôi đang sử dụng JDK 1.7.0_79


1
Tôi đã đối mặt với tình huống tương tự khi sử dụng JDK 1.7.0_xx. Vấn đề theo mặc định sẽ được giải quyết sau khi sử dụng jdk 1.8. Nhưng đôi khi chúng tôi không thể nâng cấp jdk một cách nhanh chóng. Vì vậy, vấn đề của tôi đã được giải quyết sau khi thêm cấu hình hệ thống: System.setProperty ("https.prot Protocol", "TLSv1.2"); System.setProperty ("integration.security.TLSv1.2", "true");
Ramgau
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.