Wenn ich eine SSL-Verbindung mit einigen IRC-Servern herstelle (aber nicht mit anderen - vermutlich aufgrund der bevorzugten Verschlüsselungsmethode des Servers), erhalte ich die folgende Ausnahme:
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
Letzte Ursache:
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
Ein Beispiel für einen Server, der dieses Problem demonstriert, ist aperture.esper.net:6697 (dies ist ein IRC-Server). Ein Beispiel für einen Server, der das Problem nicht demonstriert, ist kornbluth.freenode.net:6697. [Es überrascht nicht, dass alle Server in jedem Netzwerk dasselbe Verhalten aufweisen.]
Mein Code (der wie erwähnt beim Herstellen einer Verbindung zu einigen SSL-Servern funktioniert) lautet:
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();
Es ist dieser letzte startHandshake, der die Ausnahme auslöst. Und ja, mit den 'trustAllCerts' ist etwas Magisches los. Dieser Code zwingt das SSL-System, keine Zertifikate zu validieren. (Also ... kein Zertifizierungsproblem.)
Offensichtlich besteht eine Möglichkeit darin, dass der Server von esper falsch konfiguriert ist, aber ich habe gesucht und keine anderen Verweise auf Personen gefunden, die Probleme mit den SSL-Ports von esper haben, und 'openssl' stellt eine Verbindung dazu her (siehe unten). Ich frage mich also, ob dies eine Einschränkung der Java-Standard-SSL-Unterstützung ist oder so. Irgendwelche Vorschläge?
Folgendes passiert, wenn ich über 'openssl' über die Befehlszeile eine Verbindung zu aperture.esper.net 6697 herstelle:
~ $ 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)
---
Wie bereits erwähnt, wird die Verbindung nach all dem erfolgreich hergestellt, was mehr ist, als Sie für meine Java-App sagen können.
Sollte es relevant sein, verwende ich OS X 10.6.8, Java Version 1.6.0_26.
openssl
Ausgabe verwendeten Servers in der Frage sehen: "Verschlüsselung ist DHE-RSA-AES256-SHA, öffentlicher Serverschlüssel ist 2048 Bit". Und 2048> 1024 :-).
Server public key (size)
war und ist der Schlüssel im Zertifikat. s_client
im Jahr 2011 zeigte überhaupt keinen kurzlebigen Schlüssel; 1.0.2 im Jahr 2015 und Server Temp Key
höher macht mehrere Zeilen höher. Obwohl ein guter Server normalerweise die DHE-Größe mit der RSA-Auth-Größe identisch machen sollte .
Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
. Keine Ahnung, welche Größe der Server hier gesendet hat und was die Spezifikation dazu sagt.