SSL 핸드 셰이크에서 'DH 키 쌍을 생성 할 수 없습니다'예외가 발생하는 이유는 무엇입니까?


142

일부 IRC 서버와 SSL 연결을 만들 때 (그러나 서버의 선호하는 암호화 방법으로 인해 다른 서버는 아님) 다음 예외가 발생합니다.

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

최종 원인 :

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

이 문제를 보여주는 서버의 예로는 aperture.esper.net:6697(IRC 서버)이 있습니다. 문제를 나타내지 않는 서버의 예는 kornbluth.freenode.net:6697입니다. [놀랍게도, 각 네트워크의 모든 서버는 동일한 동작을 공유합니다.]

내 코드 (일부 SSL 서버에 연결할 때 작동하는 것으로 언급 됨)는 다음과 같습니다.

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

예외를 던지는 것은 마지막 startHandshake입니다. 그리고 'trustAllCerts'에는 약간의 마술이 있습니다. 이 코드는 SSL 시스템이 인증서의 유효성을 검사하지 않도록합니다. (그래서 ... 인증서 문제가 아닙니다.)

분명히 한 가지 가능성은 esper의 서버가 잘못 구성되었지만 esper의 SSL 포트에 문제가있는 사람들에 대한 다른 참조를 찾지 못했으며 'openssl'이 연결되어 있다는 것입니다 (아래 참조). 이것이 이것이 Java 기본 SSL 지원 또는 기타 제한 사항인지 궁금합니다. 어떤 제안?

커맨드 라인에서 'openssl'을 사용하여 aperture.esper.net 6697에 연결하면 어떻게됩니까?

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

언급했듯이, 결국 Java 연결에 대해 말할 수있는 것보다 성공적으로 연결됩니다.

관련이 있다면 OS X 10.6.8, Java 버전 1.6.0_26을 사용하고 있습니다.


2
그 이유는 다음과 같습니다 Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive).. 여기에서 서버가 어떤 크기를 보냈는지, 사양에 대해 무엇을 말했는지 모르겠습니다.
Paŭlo Ebermann

@ PaŭloEbermann : 실제로 "서버 openssl는 DHE-RSA-AES256-SHA, 서버 공개 키는 2048 비트"라는 질문 에서 출력에 사용 된 서버의 크기를 볼 수 있습니다 . 그리고 2048> 1024 :-).
sleske

@ 썰매 : 정확하지 않습니다. Server public key (size)증명서의 열쇠였습니다. s_client2011 년에는 임시 키가 전혀 표시되지 않았습니다. 2015 년 1.0.2 Server Temp Key이상 은 몇 줄 더 높습니다. 좋은 서버는 일반적으로 DHE 크기를 RSA 인증 크기와 동일하게 만들어야합니다.
dave_thompson_085

답변:


117

문제는 소수입니다. Java가 허용하는 최대 허용 크기는 1024 비트입니다. 이것은 알려진 문제입니다 ( JDK-6521495 참조 ).

내가 링크 한 버그 보고서는 BouncyCastle의 JCE 구현을 사용 하는 해결 방법 을 언급합니다 . 잘하면 그것은 당신을 위해 작동해야합니다.

최신 정보

버그 JDK-7044060 으로보고되었습니다. 되어 최근에 수정되었습니다.

그러나이 제한은 2048 비트로 만 높아졌습니다. 2048 비트보다 큰 크기의 경우 JDK-8072452가 있습니다. DH 키의 최대 소수를 제거합니다 . 수정은 9에 대한 것으로 보입니다.


14
+1. 썬 개발자 네트워크 계정을 가진 사람이라면 누구나이 버그에 투표하십시오.
Paŭlo Ebermann

1
감사. 더 큰 크기를 요청하는 서버가 존재하면 꽤 심각한 문제인 것 같습니다! :( BouncyCastle을 사용해 보았습니다. 우선 제공 업체로 설정하면 다른 예외 (한숨)와 충돌하며 DH에서만 사용할 수있는 명확한 방법을 볼 수는 없지만 대체 솔루션을 찾았습니다. 새 답변으로 추가하겠습니다. (예쁘지 않습니다.)
sam

3
멋있는. 이것은 최신 버전의 Java에서 수정되었습니다. 그러나 내 질문은 이전 버전을 사용하는 것에 관한 것입니다. 이전 버전을 사용할 때 때때로 작동하고 때로는 예외를 제공합니다. 왜 그렇게 임의의 행동입니까? 자바의 버그라면 결코 작동하지 않아야한다고 생각합니까?
N .. 5

2
2048 수정 프로그램은 IcedTea 2.5.3으로 백 포트되었습니다. IcedTea의 최신 버전은 4096로 증가
fuzzyTew

1
문제는 DH 프라임 크기입니다. Java가 허용하는 최대 허용 크기는 2048 비트입니다. Oracle이 한계를 확장하기를 기다리는 동안 한계가 확장 된 Excelsior Jet로 컴파일 할 수 있습니다.
user1332994 2016 년

67

"JCE (Java Cryptography Extension) 무제한 강도 관할 정책 파일"답변은 저에게는 효과가 없었지만 BouncyCastle의 JCE 제공자 제안은 효과가 없었습니다.

Mac OSC 10.7.5에서 Java 1.6.0_65-b14-462를 사용하여 수행 한 단계는 다음과 같습니다.

1) 다음 병을 다운로드하십시오.

2)이 항아리를 $ JAVA_HOME / lib / ext로 이동하십시오.

3) 다음과 같이 $ JAVA_HOME / lib / security / java.security를 ​​편집하십시오. security.provider.1 = org.bouncycastle.jce.provider.BouncyCastleProvider

JRE를 사용하여 앱을 다시 시작하고 사용해보십시오.


5
나를 위해 일한다! 비록 내가하고있는 일이 확실하지 않습니다.
다이빙

11
security.provider.2 = org.bouncycastle.jce.provider.BouncyCastleProvider가 더 잘 작동하여 기본 소프트웨어에서 오류가 발생했습니다.
TinusSky

1
이것은 나에게도 효과가 있지만 공급자를 동적으로 추가했습니다. 자세한 내용은 여기에 내 대답 을 참조하십시오.
v.ladynev

고마워, 이것은 나를 위해 일했고 Tomcat 7.0.78 소스를 성공적으로 구축하기 위해 필요했습니다.
phillipuniverse

@ mjj1409, Java 1.5에는 $ JAVA_HOME / lib / security 경로가 없습니다
Mostafa

15

여기 내 솔루션 (java 1.6)이 있는데 왜 내가 이것을 해야하는지 관심이 있습니다.

javax.security.debug = ssl에서 가끔 사용 된 암호 스위트가 TLS_DHE _...이고 때로는 TLS_ECDHE _....라는 것을 알았습니다. 나중에 BouncyCastle을 추가하면 나중에 발생합니다. TLS_ECDHE_를 선택하면 대부분의 시간 동안 작동했지만 항상 그렇지는 않았으므로 BouncyCastle 공급자를 추가해도 신뢰할 수 없습니다 (매번 같은 오류로 실패했습니다). Sun SSL 구현의 어딘가에서 때로는 DHE를 선택 하고 때로는 ECDHE를 선택 한다고 생각합니다 .

따라서 여기에 게시 된 솔루션은 TLS_DHE_ 암호를 완전히 제거하는 것입니다. 참고 : 솔루션에 BouncyCastle이 필요하지 않습니다.

따라서 다음을 수행하여 서버 인증 파일을 작성하십시오.

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

TLS_DHE_ 암호 스위트를 제외하고 SSL http get에 대한 솔루션보다 나중에 참조되므로 나중에 저장하십시오.

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

    }
}

마지막으로 사용 방법은 다음과 같습니다 (인증서 경로가 openssl에서 저장된 경우 certFilePath).

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
방금 솔루션을 테스트했습니다. 의도 한대로 작동합니다. 감사. 실제로 추가하는 것만 jdk.tls.disabledAlgorithms=DHE, ECDHE으로 JDK_HOME/jre/lib/security/java.security도 작동 하며이 모든 코드를 피하십시오.
Ludovic Guillaume

3
DHE를 비활성화하면 나를 위해 일했습니다 jdk.tls.disabledAlgorithms=DHE. 1.7.0_85-b15 사용
stephan f f.

1
JDK_HOME / jre / lib / security / java.security에 jdk.tls.disabledAlgorithms = DHE, ECDHE가 추가되었으며 정상적으로 작동했습니다! 감사합니다! 1.7.0_79 사용
Eric Na

1
ECDHE를 비활성화하지 마십시오. DHE와 다르며 소수도 사용하지 않습니다.
kubanczyk 2016 년

1
누군가 'certFilePath'를 얻는 방법을 알려주십시오. 나는 일주일 동안 이것에 붙어있다. @Zsozso
1172490 2

13

위의 답변은 정확하지만 해결 방법 측면에서 BouncyCastle 구현을 선호 공급자로 설정할 때 문제가 발생했습니다.

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

이것은 내가 찾은 하나의 포럼 스레드에서 논의되었지만 솔루션은 언급하지 않았습니다. http://www.javakb.com/Uwe/Forum.aspx/java-programmer/47512/TLS-problems

나는 그것에 만족하지 않지만 내 경우에 맞는 대안 솔루션을 찾았습니다. 해결책은 Diffie-Hellman 알고리즘을 전혀 사용할 수 없도록 설정하는 것입니다. 그런 다음 서버가 대체 알고리즘을 지원한다고 가정하면 정상적인 협상 중에 선택됩니다. 분명히 이것의 단점은 누군가가 1024 비트 이하에서 Diffie-Hellman 만 지원하는 서버를 찾는다면 실제로 이것은 이전에 작동했던 곳에서 작동하지 않는다는 것을 의미합니다.

다음은 SSLSocket이 주어지면 작동하는 코드입니다 (연결하기 전에).

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

추잡한.


1
이것이 유일한 방법은 :( 것을 슬픈 티켓이 '07 년부터 개방되었다는 것은 4 년에 대해 수행되지 않은 이상한 것을...
Vivin Paliath

저는 자바 증권을 처음 사용합니다. 이 코드를 어디에 작성해야합니까?
Shashank

이 스레드에서 모든 솔루션을 시도했지만 이것이 내 ibm jvm (ibm-java-s390x-60)에서 작동 한 유일한 솔루션이었습니다.
지안루카 그레코

@ Sam, ((SSLSocket) s)의 변수는 무엇입니까?
Mostafa

13

jdk에서 DHE를 완전히 비활성화하고 jre / lib / security / java.security를 ​​편집하고 DHE가 비활성화되었는지 확인할 수 있습니다. 처럼

jdk.tls.disabledAlgorithms=SSLv3, DHE.


4
JDK 1.7 이상에서만 사용할 수 있습니다. 링크
hoangthienan 2016 년

나를 위해 문제를 해결 JDK 1.8.0_144-b01
MrSmith42

12

제공자를 동적으로 설치할 수 있습니다.

1) 다음 병을 다운로드하십시오.

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

2) 항아리를 WEB-INF/lib(또는 클래스 패스)에 복사 하십시오.

3) 공급자를 동적으로 추가하십시오.

import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

Security.addProvider(new BouncyCastleProvider());


이 솔루션은 잘 작동하며 서버 / 환경 수준이 아닌 프로젝트 수준에서만 변경을 원했기 때문에 내 경우에 적합했습니다. 감사합니다
ishanbakshi

감사! 이것은 나를 위해 일했습니다. 제 경우에는 bcp 1.4를 가져 오기하여 이메일을 Google로 보내지 못했습니다.
Japheth Ongeri-inkalimeva

javax.net.ssl.SSLHandshakeException : 지원되지 않는 curveId : 29 Java 버전 1.6.0_27
다른 코더


6

jdk1.7.0_04를 사용중인 경우 jdk1.7.0_21로 업그레이드하십시오. 해당 업데이트에서 문제가 해결되었습니다.


2
방금 Java SE Development Kit 7u25를 다운로드 했으며 지원되는 최대 DH 크기를 결정하기 위해 작성한 작은 프로그램 에 따르면 여전히 1024입니다.
user2666524

1
JDK 1.7.0_25에서 문제가 계속 발생
Sébastien Vanmechelen

jre를 업데이트하면 나를 위해 일했습니다. .had 6.22는 7.59로 업데이트되었습니다. 문제 해결됨.
Elazaron

1
@Shashank-JDK 1.8.0_73으로 업그레이드하면 효과적입니다.
dgoverde

비트 길이가 1024보다 큰 DHKeyPairsJDK 1.7.0_91 에서 도입 되었지만 공개되지 않습니다.
다른 코더

6

잘못된 Maven 종속성이있을 수 있습니다. Maven 종속성 계층에서이 라이브러리를 찾아야합니다.

bcprov-jdk14, bcpkix-jdk14, bcmail-jdk14

이러한 종속성이 오류 인 경우 다음을 수행해야합니다.

종속성을 추가하십시오.

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

잘못된 종속성이 포함 된 이슈에서 이러한 종속성을 제외하십시오. 제 경우에는 다음과 같습니다.

<dependency>
    <groupId>com.lowagie</groupId>
    <artifactId>itext</artifactId>
    <version>2.1.7</version>
    <exclusions>
        <exclusion>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bctsp-jdk14</artifactId>                
        </exclusion>
        <exclusion>
            <groupId>bouncycastle</groupId>
            <artifactId>bcprov-jdk14</artifactId>               
        </exclusion>
        <exclusion>
            <groupId>bouncycastle</groupId>
            <artifactId>bcmail-jdk14</artifactId>               
        </exclusion>
    </exclusions>       
</dependency>

질문에 이미 많은 답변이 있으며 확인 된 답변이 하나 있습니다. 또한이 질문은 6 년 전에 제기되었습니다. 그것이 여전히 관련이 있는지 확실하지 않습니다.
David Guyon

5

Java 다운로드 사이트 에서 "JCE (Java Cryptography Extension) 무제한 강도 관할 정책 파일"을 다운로드 하고 JRE의 파일을 바꾸십시오.

이것은 나를 위해 일했고 BouncyCastle을 사용할 필요조차 없었습니다. 표준 Sun JCE는 서버에 연결할 수있었습니다.

추신. 정책 파일을 변경하기 전에 BouncyCastle을 사용하려고 할 때 동일한 오류 (ArrayIndexOutOfBoundsException : 64)가 발생하여 상황이 매우 비슷한 것 같습니다.


다른 거 없니? 또는 방금 2 파일을 폴더에 복사 했습니까?
Joergi

오랜 시간이 지났지 만 내가 기억하는 한, 그것이 내가해야 할 전부였습니다. 나중에 실행중인 Java 프로세스를 다시 시작하는 것 외에도.
mjomble

5

당신은 여전히이 문제에 물린 경우 아파치는 아파치 V> 2.4.7,이 시도 사용하고 있습니다 : http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh

URL에서 복사 :

버전 2.4.7부터 mod_ssl은 1024 비트 이상의 길이를 가진 소수를 포함하는 DH 매개 변수를 사용합니다. 그러나 Java 7 및 이전 버전은 DH 소수 크기에 대한 지원을 최대 1024 비트로 제한합니다.

java.lang.RuntimeException과 같은 예외로 Java 기반 클라이언트가 중단 된 경우 : DH 키 쌍 및 java.security.InvalidAlgorithmParameterException을 생성 할 수 없음 : 소수 크기는 64의 배수 여야하며 512-1024 (포함)의 범위 만 가능합니다. httpd logs tlsv1 경보 내부 오류 (SSL 경보 번호 80) (LogLevel 정보 이상에서) SSLCipherSuite를 사용하여 mod_ssl의 암호 목록을 재 배열하거나 (SSLHonorCipherOrder와 함께 사용 가능) 1024 비트 소수로 사용자 정의 DH 매개 변수를 사용할 수 있습니다 내장 DH 매개 변수보다 항상 우선합니다.

맞춤 DH 매개 변수를 생성하려면

openssl dhparam 1024

명령. 또는 RFC 2409, 섹션 6.2의 다음 표준 1024 비트 DH 매개 변수를 사용할 수 있습니다.

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

SSLCertificateFile 지시문을 사용하여 구성한 첫 번째 인증 파일의 끝에 "BEGIN DH PARAMETERS"및 "END DH PARAMETERS"행을 포함하는 사용자 정의 매개 변수를 추가하십시오.


클라이언트 측에서 Java 1.6을 사용하고 있으며 문제가 해결되었습니다. 암호 모음 등을 낮추지 않았지만 사용자 정의 생성 DH 매개 변수를 인증서 파일에 추가했습니다.


1024 비트 DH는 계산이 가능하지만 (지극히 비싸지 만) 깨질 수 있다고 생각합니다.
plugwash

2

Yandex Maps 서버, JDK 1.6 및 Apache HttpClient 4.2.1과 동일한 문제가 있습니다. 오류는

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

-Djavax.net.debug=all 로그에 메시지 가 있었 으므로 디버그가 활성화 되었습니다.

Could not generate DH keypair

BouncyCastle 라이브러리를 추가 bcprov-jdk16-1.46.jar하고지도 서비스 클래스에 공급자를 등록 하여이 문제를 해결했습니다.

public class MapService {

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

    public GeocodeResult geocode() {

    }

}

공급자는 처음 사용할 때 등록됩니다 MapService.


2

JDK 6을 실행하는 CentOS 서버에서 SSL 오류가 발생했습니다.

내 계획은 JDK 6과 공존하기 위해 더 높은 JDK 버전 (JDK 7)을 설치하는 것이었지만 새로운 JDK를 설치하는 것만으로 밝혀졌습니다 rpm -i 는 충분하지 않은 .

JDK 7 설치는 rpm -U 아래 그림 업그레이드 옵션으로 합니다.

1. JDK 7 다운로드

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

2. RPM 설치 실패

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

3. RPM 업그레이드 성공

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

4. 새 버전 확인

java -version
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

1

JDK 8로 업그레이드하여 문제를 해결했습니다.


1

JDK 1.6.45에서 coldfusion 8을 사용하고 이미지 대신 빨간 십자가를 제공하는 데 문제가 있었고 cfhttp가 SSL을 사용하여 로컬 웹 서버에 연결할 수 없습니다.

coldfusion 8로 재현 할 테스트 스크립트는

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

이로 인해 "I / O 예외 : 피어가 인증되지 않았습니다"라는 매우 일반적인 오류가 발생했습니다. 그런 다음 루트 및 중간 인증서를 포함하여 서버의 인증서를 java 키 저장소 및 coldfusion 키 저장소에 추가하려고 시도했지만 아무런 도움이되지 않았습니다. 그런 다음 문제를 디버깅했습니다.

java SSLPoke www.onlineumfragen.com 443

그리고있어

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

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

그런 다음 웹 서버 (내 경우에는 아파치)에 ssl에 대한 매우 현대적인 암호가 있고 상당히 제한적이며 (매수 점수 a +) 1024 비트가 넘는 강력한 diffie hellmann 키를 사용합니다. 분명히 coldfusion과 java jdk 1.6.45는 이것을 관리 할 수 ​​없습니다. odysee의 다음 단계는 Java를위한 대체 보안 공급자를 설치하는 것이 었습니다. 저는 탄력성을 결정했습니다. 또한 참조 http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/

그런 다음

bcprov-ext-jdk15on-156.jar

에서 http://www.bouncycastle.org/latest_releases.html 및 C 아래에 설치 : \ jdk6_45 \ JRE \ lib 디렉토리 \ 내선 또는 JDK가 어디에 적, 원본에이 C에서 것이다 ColdFusion에서 8의 설치 : \ JRun4 \ jre \ lib \ ext 그러나 coldfusion 디렉토리 외부에있는 최신 jdk (1.6.45)를 사용합니다. bcprov-ext-jdk15on-156.jar 파일을 \ ext 디렉토리에 두는 것이 매우 중요합니다 (이것은 2 시간 정도 소요되며 머리카락은 약간 있습니다. ;-) C : \ jdk6_45 \ jre \ lib \ security \ 파일을 편집했습니다. java.security (editpad.exe가 아닌 워드 패드 사용) 및 새 공급자에 대해 한 줄로 입력하십시오. 그 후 목록은 다음과 같습니다

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

(1 위의 새로운 것을보십시오)

그런 다음 coldfusion 서비스를 완전히 다시 시작하십시오. 당신은 그때 할 수 있습니다

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

느낌을 즐기고 ... 물론

어떤 밤과 하루. 바라건대 이것은 누군가에게 (부분적으로 또는 완전히) 도움이 될 것입니다. 궁금한 점이 있으면 info (위의 도메인)로 메일을 보내 주시기 바랍니다.


0

서버가 DH를 포함하지 않는 암호를 지원하는 경우 클라이언트가 해당 암호를 강제로 선택하고 DH 오류를 피할 수 있습니다. 같은 :

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

정확한 암호를 지정하면 장기적으로 손상되기 쉽습니다.


0

우리는 인터넷을 서핑하는 몇 시간 후에 쉽게 해결하기 위해 동일한 정확한 예외 오류가 반환되었습니다.

oracle.com에서 찾을 수있는 최고 버전의 jdk를 다운로드하여 설치 한 다음 Jboss 응용 프로그램 서버를 설치된 새 jdk의 디렉토리로 지정했습니다.

Jboss 재시작, 재 처리, 문제 해결 !!!


0

Bamboo 5.7 + Gradle project + Apache 에서이 오류가 발생했습니다. Gradle은 SSL을 통해 서버 중 하나에서 일부 종속성을 얻으려고했습니다.

해결책:

  1. DH 매개 변수 생성 :

OpenSSL 사용시 :

openssl dhparam 1024

출력 예 :

-----BEGIN DH PARAMETERS-----
MIGHfoGBALxpfMrDpImEuPlhopxYX4L2CFqQov+FomjKyHJrzj/EkTP0T3oAkjnS
oCGh6p07kwSLS8WCtYJn1GzItiZ05LoAzPs7T3ST2dWrEYFg/dldt+arifj6oWo+
vctDyDqIjlevUE+vyR9MF6B+Rfm4Zs8VGkxmsgXuz0gp/9lmftY7AgEC
-----END DH PARAMETERS-----
  1. 인증서 파일에 출력 추가 (Apache- SSLCertificateFileparam)

  2. 아파치 다시 시작

  3. 대나무를 다시 시작

  4. 프로젝트를 다시 빌드하십시오


0

IBM JDK를 사용하여 Java SVN 클라이언트로 svn.apache.org에 액세스하는 동안 유사한 오류가 발생했습니다. 현재 svn.apache.org는 클라이언트 암호 환경 설정을 사용합니다.

패킷 캡처 / javax.net.debug = ALL로 한 번만 실행 한 후 단일 DHE 암호 만 블랙리스트에 올릴 수 있었고 상황이 나에게 도움이되었습니다 (대신 ECDHE 협상).

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

클라이언트를 변경하기가 쉽지 않을 때의 빠른 수정 방법.


0

최근에 나는 동일한 문제와에서 업그레이드 JDK 버전 이후에이 1.6.0_45jdk1.7.0_191 문제를 해결.


-1

나에게 다음 명령 줄이 문제를 해결했습니다.

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

JDK 1.7.0_79를 사용하고 있습니다


1
JDK 1.7.0_xx를 사용하여 동일한 상황에 직면했습니다. jdk 1.8을 사용하면 기본적으로 문제가 해결됩니다. 그러나 언젠가 jdk를 빠르게 업그레이드 할 수 없습니다. 따라서 시스템 구성을 추가 한 후에 문제가 해결되었습니다. System.setProperty ( "https.protocols", "TLSv1.2"); System.setProperty ( "deployment.security.TLSv1.2", "true");
Ramgau
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.