Lorsque j'établis une connexion SSL avec certains serveurs IRC (mais pas d'autres - probablement en raison de la méthode de cryptage préférée du serveur), j'obtiens l'exception suivante:
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
Cause finale:
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
Un exemple de serveur illustrant ce problème est aperture.esper.net:6697 (il s'agit d'un serveur IRC). Un exemple de serveur qui ne présente pas le problème est kornbluth.freenode.net:6697. [Sans surprise, tous les serveurs de chaque réseau partagent le même comportement respectif.]
Mon code (qui, comme indiqué, fonctionne lors de la connexion à certains serveurs SSL) est:
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();
C'est ce dernier startHandshake qui lève l'exception. Et oui, il y a de la magie avec les «trustAllCerts»; ce code force le système SSL à ne pas valider les certificats. (Donc ... pas un problème de cert.)
De toute évidence, une possibilité est que le serveur d'esper est mal configuré, mais j'ai cherché et n'ai trouvé aucune autre référence à des personnes ayant des problèmes avec les ports SSL d'esper, et 'openssl' s'y connecte (voir ci-dessous). Je me demande donc s'il s'agit d'une limitation du support SSL par défaut de Java, ou quelque chose. Aucune suggestion?
Voici ce qui se passe lorsque je me connecte à aperture.esper.net 6697 en utilisant 'openssl' depuis la ligne de commande:
~ $ 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)
---
Comme indiqué, après tout cela, il se connecte avec succès, ce qui est plus que ce que vous pouvez dire pour mon application Java.
Si cela est pertinent, j'utilise OS X 10.6.8, Java version 1.6.0_26.
openssl
sortie dans la question: "Le chiffrement est DHE-RSA-AES256-SHA, la clé publique du serveur est de 2048 bits". Et 2048> 1024 :-).
Server public key (size)
était, et est, la clé du cert. s_client
en 2011 n'a pas montré du tout de clé éphémère; 1.0.2 en 2015 et plus fait Server Temp Key
plusieurs lignes plus haut. Bien qu'un bon serveur doive généralement rendre la taille DHE identique à la taille d'authentification RSA.
Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
. Aucune idée de la taille envoyée par le serveur ici, et de ce que la spécification dit à ce sujet.