Como gerar novos parâmetros Diffie-Hellman de 2048 bits com o Java keytool?

9

Não somos especialistas, tentando - até agora sem sucesso - atualizar nossas configurações de servidor da web (JBoss-5.1.0.GA) para atender aos padrões Diffie-Hellman. Depois de executar um teste em https://weakdh.org/sysadmin.html , somos informados de que precisamos "gerar novos parâmetros Diffie-Hellman de 2048 bits". No passado, geramos chaves com a Java keytool, mas não conseguimos encontrar nenhuma informação sobre como gerar um novo parâmetro Diffie-Hellman de 2048 bits com a Java keytools. Alguém sabe como fazer isso ou poderia nos indicar a direção certa? Obrigado!

user2072931
fonte

Respostas:

13

Você não pode fazer isso com o keytool. Primeiro, keytoolnão suporta DH. Segundo, keytoolnão gera parâmetros por si só para qualquer algoritmo, apenas uma chave privada / par de chaves. Terceiro, quando keytoolgera um par de chaves, também gera um certificado autoassinado (que às vezes é substituído por um certificado "real" emitido pela CA) e é impossível gerar um certificado autoassinado para o DH porque o DH não assina. Você pode escrever um programa Java muito simples (cerca de 10 linhas) para gerar parâmetros DH. Mas provavelmente não faria nenhum bem porque:

Java não aceita parâmetros DHE aqui de qualquer maneira. O JbossWS (o servidor da web Jboss, mais tarde Wildfly) é um fork do Tomcat e normalmente usa a implementação Java do SSL / TLS, JSSE. Até o Java 7, o JSSE usa seus próprios parâmetros DHE de 768 bits, que são inaceitavelmente fracos. (Exceto nos conjuntos EXPORT em que o JSSE obedece ao requisito RFC para o DH-512, que é totalmente interrompido, mas os conjuntos EXPORT são totalmente projetados de qualquer maneira e são desativados por padrão no Java 7 em diante.) O Java 8 JSSE permite que você controla o tamanho dos parâmetros DHE, mas não o valor real.

Suas opções (algumas sobrepostas) são:

Use o Java 8. JSSE no Java 8, mas não antes, o DHE tem como padrão 1024 bits, que a maioria das autoridades considera fortes o suficiente, apesar de o fracodh.org não, e permite que você especifique mais, consulte https://docs.oracle.com /javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#customizing_dh_keys e para o plano de fundo /programming/30352105/how-to-set-custom-dh-group-in-java -sslengine-to-prevent-logjam-attack . Observe que se você tiver algum cliente Java antes do Java 8, eles falharão se o servidor usar DHE acima de 1024 bits. Não conheço outros clientes que tenham esse problema, mas teste o seu antes de se comprometer com essa alteração.

Ative o ECDHE. O JSSE no Java 7 e posterior implementa o ECDHE, que não está sujeito a pré-computação como DHE, (normalmente) usando o P-256, que é mais do que forte o suficiente. (Embora algumas pessoas não confiem em nenhuma das curvas NIST ECC porque o NIST em geral é influenciado pela NSA, embora nenhum código aberto que eu conheça tenha mostrado um problema especificamente nas curvas ECC.) Java 6 realmente tem a parte JSSE para ECDHE mas só será ativado se a JVM tiver um "provedor" criptográfico para primitivas ECC, o que o Java 6 não possui. bcprov - * - jdk15on de http://www.bouncycastle.org/ é um provedor JCE para uma variedade de primitivas criptográficas Java, incluindo ECC, portanto, se você adicionar o jar ao seu JRE/lib/exte adicionar org.bouncycastle.jce.provider.BouncyCastleProviderà lista em JRE/lib/security/java.security(ou faça umaSecurity.add/insertProvider()em algum lugar no início do seu código) Java 6 pode executar ECDHE. É claro que você deve ter o Java 6 ainda em uso é uma questão por si só.

Há alguns anos, o suporte ao ECDHE em navegadores e outros clientes era duvidoso, mas hoje o AFAIK todos os navegadores atualizados o suportam e o preferem ao DHE - ou seja, o hello navegador lista os pacotes ECDHE antes dos pacotes DHE, portanto que, se o servidor implementar os dois, deverá escolher ECDHE. Clientes que não são navegadores talvez não; teste para ter certeza.

Desative o DHE. Você pode configurar a lista de cifras no atributo Connector para excluir cifras DHE; enquanto você estiver nisso, também exclua staticDH e staticECDH, que são inúteis, e (único) DES e (todos) "EXPORT", se presentes (Java 6). Isso significa que navegadores e clientes que não fazem ECHDE ficarão presos ao RSA comum e sem Forward Secrecy, mas pelo menos eles têm sigilo "atual". Não me lembro com certeza, mas acho que a configuração do 5.1 Connector ainda estava em algum lugar $server/deploy/jbossweb/server.xml.

Tente nativo. O Tomcat, do qual eu disse que o JbossWS começou, tem uma opção para implementar HTTPS (SSL / TLS) usando "nativo" ou "APR", que na verdade é OpenSSL dentro do JSSE. Eu tive um sucesso misto em fazer com que essa opção funcionasse no JbossWS e não me lembro do 5.1. Se o seu JbossWS tiver uma opção nativa do TC viável e se puder lidar com a configuração de parâmetros DH, use o openssl para gerar os parâmetros DH e as instruções nativas do JbossWS para configurá-los.

dave_thompson_085
fonte
Obrigado por esta ótima informação. Em última análise, a resposta para nós não envolveu o keytool, apenas as alterações no arquivo server.xml, mas vou verificar esta resposta.
user2072931
4

Na verdade, você pode especificar parâmetros DHE personalizados com versões recentes do Java 8 . Isso é independente do aplicativo (contanto que ele use a implementação JSSE TLS).

Você primeiro precisa especificar o tamanho da chave DHE a ser usada ( -Djdk.tls.ephemeralDHKeySize=1024ou -Djdk.tls.ephemeralDHKeySize=2048). No servidor, isso usará uma combinação predefinida de gerador / prime para o DHE. Com o Java 8, apenas 1024 ou 2048 podem ser usados, o JDK 9 suportará tamanhos maiores .

Se você desejar fornecer uma combinação diferente, poderá especificá-las em jre / lib / security / Java.security com a jdk.tls.server.defaultDHEParameterspropriedade security (desde 8u51). Ele pega uma lista de Parâmetros (um para cada tamanho de chave usado) e deve conter o prime e o Generator (normalmente 2 ou 5) como hexadecimal.

Se você costumava openssl dhparam -out dhparam2048.pem 2048gerar um novo par, pode usar openssl dhparam -noout -text -check -in dhparam2048.pempara ler e imprimir esse arquivo no modo de texto. Você precisará copiar e colar o texto nas propriedades de segurança Java (usando tr -d ':'para remover a :representação hexadecimal openssl)

Aqui está uma amostra (apenas 1024 bis):

>openssl dhparam -in p -check -text -noout | tr -d ':'
PKCS#3 DH Parameters: (1024 bit)
    prime:
       00f7a63b59edcc43a43df12077f0e9
        14129c20a73cef95f919896e608ebc
        8722776c948765bbbf61542e118329
        6c6ea74ecbded3a93aff77a062aba4
        fcf04fc01030e65077f5a802605058
        65b836368dd5ea389d77691fac0f2c
        f7a161c51c8e97ddecb3cf7f872b0c
        cfaf54373d5203edcabc575e871bb1
        107ec2f30c78ebf403
    generator: 2 (0x2)
DH parameters appear to be ok.

E isso resulta em

jdk.tls.server.defaultDHEParameters= \
    { \
        00f7a63b59edcc43a43df12077f0e9 \
        14129c20a73cef95f919896e608ebc \
        8722776c948765bbbf61542e118329 \
        6c6ea74ecbded3a93aff77a062aba4 \
        fcf04fc01030e65077f5a802605058 \
        65b836368dd5ea389d77691fac0f2c \
        f7a161c51c8e97ddecb3cf7f872b0c \
        cfaf54373d5203edcabc575e871bb1 \
        107ec2f30c78ebf403, 2 }

Você deve reiniciar o servidor e verificar se ele realmente usa esse prime (e não os padrão), pois o processo não é direto, portanto, muita coisa pode dar errado. O padrão é definido na origem , para 2048 bits o prime é do rascunho do TLS FFDHE.

Por exemplo, ao executar o openssl s_client, posso ver o 1024bit prime ( ffffff ffffffffffc90f ... 5381ffffffffffffffffff ) ao conectar-se a um servidor JSSE Java 8:

>openssl s_client -msg -cipher DHE-RSA-AES128-SHA256 -connect localhost:1234
...
<<< TLS 1.2 Handshake [length 018f], ServerKeyExchange
0c 00 01 8b 00 80 ff ff ff ff ff ff ff ff c9 0f
da a2 21 68 c2 34 c4 c6 62 8b 80 dc 1c d1 29 02
4e 08 8a 67 cc 74 02 0b be a6 3b 13 9b 22 51 4a
08 79 8e 34 04 dd ef 95 19 b3 cd 3a 43 1b 30 2b
0a 6d f2 5f 14 37 4f e1 35 6d 6d 51 c2 45 e4 85
b5 76 62 5e 7e c6 f4 4c 42 e9 a6 37 ed 6b 0b ff
5c b6 f4 06 b7 ed ee 38 6b fb 5a 89 9f a5 ae 9f
24 11 7c 4b 1f e6 49 28 66 51 ec e6 53 81 ff ff
ff ff ff ff ff ff 00 01 02 ...

Em vez disso, você deve ver seus parâmetros personalizados quando instalado.

Os parâmetros padrão para Java 7 (768bit) seriam "e9e642 ... 7a3daf" com um gerador longo "30470ad..529252", conforme definido no ParameterCache .

eckes
fonte
3

Eu tenho passado pelo mesmo problema, mas da Glassfish.

Primeiramente, eu recomendaria (se você puder) colocar algum tipo de proxy reverso na frente do servidor JBoss, pois ele removerá o link entre a segurança de cifra / certificado e a versão do Java que você está executando.

Para obter um comprimento de chave DH Efêmero maior que 768 bits, você precisa estar executando o Java 8. 1024 é o novo padrão e você pode ir até 2048 usando os jdk.tls.ephemeralDHKeySize(detalhes: customizando chaves DH ). Pelo que pude encontrar, não há conceito de regenerar os parâmetros-chave separadamente em Java.

David Hutchison
fonte
Obrigado por esta sugestão de uma alternativa. Podemos investigar isso no futuro.
user2072931
Agora existe, consulte serverfault.com/a/798036/4591
eckes
para glassfish / cachorra / cachorra-micro para desativar o DHE cifras adicionar <ssl tls-enabled="false" classname="com.sun.enterprise.security.ssl.GlassfishSSLImpl" tls11-enabled="false" cert-nickname="s1as" ssl3-tls-ciphers="+TLS_RSA_WITH_AES_256_CBC_SHA,+TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA256,+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA256,+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,+TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA256,+TLS_ECDH_RSA_WITH_AES_256_GCM_SHA256"></ssl>ao <protocol name="http-listener-2" security-enabled="true">conector SSL
Markus