Por que o handshake SSL fornece a exceção 'Não foi possível gerar o par de chaves DH'?

142

Quando faço uma conexão SSL com alguns servidores IRC (mas não outros - provavelmente devido ao método de criptografia preferido do servidor), recebo a seguinte exceção:

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

Causa final:

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

Um exemplo de servidor que demonstra esse problema é a abertura.esper.net:6697 (este é um servidor IRC). Um exemplo de servidor que não demonstra o problema é kornbluth.freenode.net:6697. [Não é de surpreender que todos os servidores em cada rede compartilhem o mesmo comportamento respectivo.]

Meu código (que conforme observado funciona quando se conecta a alguns servidores 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();

É esse último startHandshake que lança a exceção. E sim, há alguma mágica acontecendo com o 'trustAllCerts'; esse código força o sistema SSL a não validar certs. (Então ... não é um problema de certificação.)

Obviamente, uma possibilidade é que o servidor do esper esteja configurado incorretamente, mas eu procurei e não encontrei outras referências a pessoas com problemas nas portas SSL do esper, e o 'openssl' se conecta a ele (veja abaixo). Então, eu estou querendo saber se isso é uma limitação do suporte SSL Java padrão, ou algo assim. Alguma sugestão?

Aqui está o que acontece quando eu me conecto ao aperture.esper.net 6697 usando 'openssl' na linha de comando:

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

Como observado, depois de tudo isso, ele se conecta com êxito, o que é mais do que você pode dizer para o meu aplicativo Java.

Caso seja relevante, estou usando o OS X 10.6.8, versão Java 1.6.0_26.

sam
fonte
2
A razão parece ser a seguinte: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive). Não faço ideia de qual tamanho foi enviado pelo servidor aqui e o que a especificação diz sobre isso.
Pa Elo Ebermann 27/07
@ PaŭloEbermann: Na verdade, você pode ver o tamanho do servidor usado na opensslsaída na pergunta: "A cifra é DHE-RSA-AES256-SHA, a chave pública do servidor é de 2048 bits". E 2048> 1024 :-).
sleske
@lesleske: não exatamente. Server public key (size)foi e é a chave do certificado. s_clientem 2011 não mostrou chave efêmera; 1.0.2 em 2015 e acima faz Server Temp Keyvárias linhas mais altas. Embora um bom servidor geralmente deva ter o tamanho DHE igual ao tamanho da autenticação RSA.
Dave_thompson_085

Respostas:

117

O problema é o tamanho principal. O tamanho máximo aceitável aceito pelo Java é 1024 bits. Este é um problema conhecido (consulte JDK-6521495 ).

O relatório de bug ao qual vinculei menciona uma solução alternativa usando a implementação JCE do BouncyCastle. Espero que isso funcione para você.

ATUALIZAR

Isso foi relatado como bug JDK-7044060 e corrigido recentemente.

Observe, no entanto, que o limite foi aumentado apenas para 2048 bits. Para tamanhos> 2048 bits, existe JDK-8072452 - Remova o tamanho máximo primário das chaves DH ; a correção parece ser para 9.

Vivin Paliath
fonte
14
+1. Todo mundo que tiver uma conta da Sun Developer Network, vote neste bug.
Paŭlo Ebermann 27/07
1
Obrigado. Parece um problema bastante sério, dada a existência de servidores que solicitam um tamanho maior! :( Tentei o BouncyCastle; se você configurá-lo como provedor preferencial, ele trava com uma exceção diferente (suspiro) e não vejo uma maneira óbvia de usá-lo apenas para o DH. No entanto, encontrei uma solução alternativa, que eu vai adicionar como uma nova resposta (não é bonito.).
sam
3
Legal. Isso foi corrigido nas versões mais recentes do Java. Mas minha pergunta é sobre o uso da versão mais antiga. Quando uso a versão mais antiga, às vezes funciona e às vezes dá uma exceção acima .. Por que um comportamento tão aleatório? Se é um bug em java, então eu acho que nunca deve funcionar?
N ..
2
A correção 2048 foi portada para o IcedTea 2.5.3. Versões mais recentes do IcedTea aumentou para 4096.
fuzzyTew
1
O problema é o tamanho principal da DH. O tamanho máximo aceitável aceito pelo Java é 2048 bits. Enquanto aguardamos a Oracle expandir o limite, você pode compilar com o Excelsior Jet, que possui um limite expandido.
User1332994
67

A resposta "Arquivos de política de jurisdição de força ilimitada da Java Cryptography Extension (JCE)" não funcionou para mim, mas a sugestão do provedor JCE do The BouncyCastle funcionou.

Aqui estão as etapas que eu segui usando o Java 1.6.0_65-b14-462 no Mac OSC 10.7.5

1) Faça o download destes frascos:

2) mova esses jars para $ JAVA_HOME / lib / ext

3) edite $ JAVA_HOME / lib / security / java.security da seguinte maneira: security.provider.1 = org.bouncycastle.jce.provider.BouncyCastleProvider

reinicie o aplicativo usando o JRE e tente

mjj1409
fonte
5
funciona para mim! embora não tenha muita certeza do que estou fazendo.
precisa saber é o seguinte
11
security.provider.2 = org.bouncycastle.jce.provider.BouncyCastleProvider funcionou melhor, colocando-o em 1. resultou em erros no software padrão.
TinusSky
1
Isso funciona para mim também, mas adicionei um provedor dinamicamente. Consulte minha resposta aqui para obter detalhes.
v.ladynev
Muito obrigado, isso funcionou para mim e foi necessário para criar com êxito a fonte do Tomcat 7.0.78.
Phillipuniverse
@ mjj1409, em Java 1.5 não temos $ caminho JAVA_HOME / lib / security
Mostafa
15

Aqui está minha solução (java 1.6), também estaria interessado por que eu tive que fazer isso:

Percebi no javax.security.debug = ssl, que às vezes o conjunto de cifras usado é TLS_DHE _... e às vezes é TLS_ECDHE _..... Mais tarde isso aconteceria se eu adicionasse o BouncyCastle. Se TLS_ECDHE_ foi selecionado, na maioria das vezes funcionou, mas NÃO SEMPRE, portanto, a adição do mesmo provedor BouncyCastle não era confiável (falha com o mesmo erro, a cada duas vezes). Eu acho que em algum lugar da implementação do Sun SSL, às vezes, escolhe DHE , às vezes, escolhe ECDHE .

Portanto, a solução postada aqui depende da remoção completa das cifras TLS_DHE_. NOTA: BouncyCastle NÃO é necessário para a solução.

Portanto, crie o arquivo de certificação do servidor:

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

Salve isso como será mencionado posteriormente, pois aqui está a solução para um HTTP get HTTP, excluindo os conjuntos de cifras 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));
        }

    }
}

Finalmente, aqui está como ele é usado (certFilePath, se o caminho do certificado foi salvo no 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
fonte
9
Acabei de testar sua solução. Está funcionando como pretendido. Obrigado. Na verdade, apenas adicionando jdk.tls.disabledAlgorithms=DHE, ECDHEem JDK_HOME/jre/lib/security/java.securitytambém funciona e evitar todo este código.
Ludovic Guillaume
3
Apenas incapacitante DHE trabalhou para mim: jdk.tls.disabledAlgorithms=DHE. Usando 1.7.0_85-b15.
Stephan f
1
Adicionado jdk.tls.disabledAlgorithms = DHE, ECDHE no JDK_HOME / jre / lib / security / java.security e funcionou bem! Obrigado! Usando 1.7.0_79
Eric Na
1
Não desative o ECDHE. É diferente do DHE e nem usa números primos.
precisa saber é o seguinte
1
Alguém pode me dizer como posso obter o 'certFilePath'. Estou preso nisso há uma semana. @Zsozso
user1172490
13

A resposta acima está correta, mas em termos de solução alternativa, tive problemas com a implementação do BouncyCastle quando a defini como provedor preferencial:

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

Isso também é discutido em um tópico do fórum que encontrei, que não menciona uma solução. http://www.javakb.com/Uwe/Forum.aspx/java-programmer/47512/TLS-problems

Encontrei uma solução alternativa que funciona para o meu caso, embora não esteja nada feliz com isso. A solução é configurá-lo para que o algoritmo Diffie-Hellman não esteja disponível. Supondo que o servidor suporte um algoritmo alternativo, ele será selecionado durante a negociação normal. Obviamente, a desvantagem disso é que, se alguém de alguma forma conseguir encontrar um servidor que suporte apenas o Diffie-Hellman a 1024 bits ou menos, isso significa que ele não funcionará onde costumava trabalhar antes.

Aqui está o código que funciona com um SSLSocket (antes de você conectá-lo):

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

Desagradável.

sam
fonte
1
Triste que esta é a única maneira :( Isso bilhete foi aberto desde '07 Estranho que nada foi feito sobre isso em 4 anos...
Vivin Paliath
Eu sou novo em títulos java. Por favor, ajude onde devo escrever este pedaço de código?
Shashank
Eu tentei todas as soluções neste segmento e essa foi a única que funcionou com o meu ibm jvm (ibm-java-s390x-60).
Gianluca Greco
@ Sam, o que é variável s ((SSLSocket) s)?
Mostafa
13

Você pode desativar completamente o DHE no seu jdk, editar jre / lib / security / java.security e garantir que o DHE esteja desativado, por exemplo. gostar

jdk.tls.disabledAlgorithms=SSLv3, DHE.

Tor
fonte
4
isso está disponível apenas no JDK 1.7 e posterior. link
hoangthienan
Resolvido o problema para mim JDK 1.8.0_144-b01
MrSmith42
12

Você pode instalar o provedor dinamicamente:

1) Faça o download destes frascos:

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

2) Copie os frascos para WEB-INF/lib (ou seu caminho de classe)

3) Adicione provedor dinamicamente:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

Security.addProvider(new BouncyCastleProvider());

angelcorral
fonte
Essa solução funciona bem e foi adequada para o meu caso, pois eu queria fazer as alterações apenas no nível do projeto e não no servidor / ambiente. Graças
ishanbakshi
Obrigado! isso funcionou para mim. No meu caso, foi itext importando o bcp 1.4 causando e-mails para o google falharem.
Jafé Ongeri - inkalimeva
Estou ficando javax.net.ssl.SSLHandshakeException: curveId não suportado: 29 com java versão 1.6.0_27
Outro codificador
6

Se você estiver usando o jdk1.7.0_04, atualize para o jdk1.7.0_21. O problema foi corrigido nessa atualização.

Lekkie
fonte
2
Eu apenas o download Java SE Development Kit 7u25, e de acordo com o pequeno programa que escrevi para determinar o tamanho máximo suportado DH , ainda é 1024.
user2666524
1
Problema ainda existe com o JDK 1.7.0_25
Sébastien Vanmechelen
O jre de atualização funcionou para mim .had 6.22 atualizado para 7.59. problema resolvido.
Elazaron
1
@ Shanks - Atualizar para o JDK 1.8.0_73 funcionou para mim.
21716 dgoverde
DHKeyPairs com tamanhos de bits maiores que 1024 introduzidos no JDK 1.7.0_91, mas não estão disponíveis ao público.
Outro codificador
6

É possível que você tenha dependências incorretas do Maven. Você deve encontrar estas bibliotecas na hierarquia de dependência do Maven:

bcprov-jdk14, bcpkix-jdk14, bcmail-jdk14

Se você possui essas dependências, esse é o erro e deve fazer isso:

Adicione a dependência:

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

Exclua essas dependências do artefato que incluiu as dependências incorretas, no meu caso, é:

<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
fonte
A pergunta já recebeu muitas respostas e tem uma resposta validada. Além disso, a pergunta foi feita há mais de 6 anos. Não tenho certeza se ainda é relevante.
David Guyon
5

Tente baixar "Arquivos de política de jurisdição de força ilimitada da Java Cryptography Extension (JCE)" no site de download do Java e substituindo os arquivos no seu JRE.

Isso funcionou para mim e eu nem precisei usar o BouncyCastle - o Sun JCE padrão conseguiu conectar-se ao servidor.

PS. Eu recebi o mesmo erro (ArrayIndexOutOfBoundsException: 64) quando tentei usar o BouncyCastle antes de alterar os arquivos de políticas, então parece que nossa situação é muito semelhante.

mjomble
fonte
você fez mais alguma coisa? ou apenas copiou os 2 arquivos para a pasta?
Joergi
Já faz um tempo, mas pelo que me lembro, era tudo o que eu precisava fazer. Além de reiniciar qualquer processo Java em execução posteriormente.
Mjomble
5

Se você ainda é mordido por esse problema E está usando o Apache httpd v> 2.4.7, tente o seguinte: http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh

copiado do URL :

A partir da versão 2.4.7, o mod_ssl usará parâmetros DH que incluem números primos com comprimentos superiores a 1024 bits. No entanto, o Java 7 e anteriores limitam seu suporte a tamanhos principais DH a um máximo de 1024 bits.

Se o seu cliente baseado em Java interromper com exceções como java.lang.RuntimeException: não foi possível gerar o par de chaves DH e java.security.InvalidAlgorithmParameterException: o tamanho principal deve ser múltiplo de 64 e pode variar de 512 a 1024 (inclusive) e httpd logs erro interno do alerta tlsv1 (número de alerta SSL 80) (nas informações do LogLevel ou superior), você pode reorganizar a lista de cifras do mod_ssl com o SSLCipherSuite (possivelmente em conjunto com SSLHonorCipherOrder) ou pode usar parâmetros DH personalizados com um prime de 1024 bits , que sempre terá precedência sobre qualquer um dos parâmetros DH internos.

Para gerar parâmetros DH personalizados, use o

openssl dhparam 1024

comando. Como alternativa, você pode usar os seguintes parâmetros DH padrão de 1024 bits do RFC 2409, seção 6.2:

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

Adicione os parâmetros personalizados, incluindo as linhas "BEGIN DH PARAMETERS" e "END DH PARAMETERS" no final do primeiro arquivo de certificado que você configurou usando a diretiva SSLCertificateFile.


Estou usando o java 1.6 no lado do cliente e ele resolveu meu problema. Eu não abaixei os conjuntos de cifras ou algo parecido, mas adicionei um parâmetro DH gerado personalizado ao arquivo cert ..

pka
fonte
Esteja ciente de que agora acredita-se que o DH de 1024 bits seja computacionalmente viável (embora extremamente caro) quebrar.
plugwash
2

Eu tenho o mesmo problema com o servidor Yandex Maps, JDK 1.6 e Apache HttpClient 4.2.1. O erro foi

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

com depuração ativada, -Djavax.net.debug=all havia uma mensagem em um log

Could not generate DH keypair

Corrigi esse problema adicionando a biblioteca BouncyCastle bcprov-jdk16-1.46.jare registrando um provedor em uma classe de serviço de mapa

public class MapService {

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

    public GeocodeResult geocode() {

    }

}

Um provedor é registrado no primeiro uso de MapService.

v.ladynev
fonte
2

Encontrei o erro SSL em um servidor CentOS executando o JDK 6.

Meu plano era instalar uma versão mais alta do JDK (JDK 7) para coexistir com o JDK 6, mas acontece que apenas a instalação do JDK mais recente rpm -inão era suficiente.

A instalação do JDK 7 seria bem-sucedida apenas com o rpm -U opção de atualização conforme ilustrado abaixo.

1. Faça o download do 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. Falha na instalação do 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. A atualização do RPM foi bem-sucedida

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. Confirme a nova versão

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

Resolvido o problema, atualizando para o JDK 8.

anre
fonte
1

Eu uso o coldfusion 8 no JDK 1.6.45 e tive problemas em me dar apenas cruzes vermelhas em vez de imagens, e também com o cfhttp não conseguir conectar-se ao servidor da web local com ssl.

meu script de teste para reproduzir com o coldfusion 8 foi

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

isso me deu o erro bastante genérico de "Exceção de E / S: ponto não autenticado". Tentei adicionar certificados do servidor, incluindo certificados raiz e intermediários ao keystore java e também ao keystore do coldfusion, mas nada ajudou. então eu depurei o problema com

java SSLPoke www.onlineumfragen.com 443

e pegou

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

e

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

Então tive a ideia de que o servidor da web (apache no meu caso) tinha cifras muito modernas para ssl e é bastante restritivo (qualys obtém um +) e usa chaves hellmann fortes e difíceis com mais de 1024 bits. obviamente, o coldfusion e o java jdk 1.6.45 não conseguem gerenciar isso. O próximo passo no odysee foi pensar em instalar um provedor de segurança alternativo para java, e eu decidi pelo castelo insuflável. consulte também http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/

Eu então baixei o

bcprov-ext-jdk15on-156.jar

em http://www.bouncycastle.org/latest_releases.html e instalei-o em C: \ jdk6_45 \ jre \ lib \ ext ou onde quer que esteja o seu jdk, na instalação original do coldfusion 8, ele estaria em C: \ JRun4 \ jre \ lib \ ext, mas eu uso um jdk (1.6.45) mais recente, localizado fora do diretório do coldfusion. é muito importante colocar o bcprov-ext-jdk15on-156.jar no diretório \ ext (isso me custou cerca de duas horas e um pouco de cabelo ;-); depois editei o arquivo C: \ jdk6_45 \ jre \ lib \ security \ java.security (com o wordpad não com o editor.exe!) e coloque em uma linha para o novo provedor. depois a lista parecia

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

(veja o novo na posição 1)

em seguida, reinicie o serviço de fusão a frio completamente. você pode então

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

e aproveite a sensação ... e claro

que noite e que dia. Espero que isso ajude (parcial ou totalmente) a alguém por aí. se você tiver alguma dúvida, envie-me um e-mail para info ... (domínio acima).

Raffael Meier
fonte
0

Se o servidor suportar uma cifra que não inclua DH, você poderá forçar o cliente a selecioná-la e evitar o erro DH. Tal como:

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

Lembre-se de que especificar uma cifra exata pode sofrer rupturas a longo prazo.

Jason Martin
fonte
0

Obtivemos o mesmo erro de exceção exato, para corrigi-lo depois de horas navegando na Internet.

Baixamos a versão mais alta do jdk que encontramos no oracle.com, instalamos e apontamos o servidor de aplicativos Jboss para o diretório do novo jdk instalado.

Jboss reiniciado, reprocessado, problema corrigido !!!

Peter Azuka Molokwu
fonte
0

Eu tenho esse erro com o Bamboo 5.7 + projeto Gradle + Apache. Gradle tentou obter algumas dependências de um de nossos servidores via SSL.

Solução:

  1. Gere DH Param:

com o OpenSSL:

openssl dhparam 1024

saída de exemplo:

-----BEGIN DH PARAMETERS-----
MIGHfoGBALxpfMrDpImEuPlhopxYX4L2CFqQov+FomjKyHJrzj/EkTP0T3oAkjnS
oCGh6p07kwSLS8WCtYJn1GzItiZ05LoAzPs7T3ST2dWrEYFg/dldt+arifj6oWo+
vctDyDqIjlevUE+vyR9MF6B+Rfm4Zs8VGkxmsgXuz0gp/9lmftY7AgEC
-----END DH PARAMETERS-----
  1. Anexar saída ao arquivo de certificado (para Apache - SSLCertificateFileparam)

  2. Reinicie o apache

  3. Reinicie o Bamboo

  4. Tente criar o projeto novamente

Evgeny Lebedev
fonte
0

Eu costumava receber um erro semelhante ao acessar svn.apache.org com clientes SVN Java usando um IBM JDK. Atualmente, o svn.apache.org usa as preferências de cifra dos clientes.

Depois de executar apenas uma vez com um pacote capture / javax.net.debug = ALL, consegui colocar na lista negra apenas uma única cifra DHE e as coisas funcionam para mim (o ECDHE é negociado).

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

Uma solução rápida e agradável quando não é fácil alterar o cliente.

covener
fonte
0

Recentemente, tenho o mesmo problema e após a atualização da versão do jdk de 1.6.0_45 para o jdk1.7.0_191, que resolveu o problema.

Sam
fonte
-1

Para mim, a seguinte linha de comando corrigiu o problema:

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

Estou usando o JDK 1.7.0_79

rico-chango
fonte
1
Eu enfrentei a mesma situação usando o JDK 1.7.0_xx. Por padrão, o problema será resolvido após o uso do jdk 1.8. Mas em algum momento não podemos atualizar o jdk rapidamente. Portanto, meu problema foi resolvido depois de adicionar a configuração do sistema: System.setProperty ("https.protocols", "TLSv1.2"); System.setProperty ("deployment.security.TLSv1.2", "true");
Ramgau # 03