Warum funktioniert der SSL-handshake geben 'Konnte nicht erzeugen DH-Schlüsselpaar' Ausnahme?

Wenn ich eine SSL-Verbindung mit IRC-Server (in anderen aber nicht - vermutlich weil die server das bevorzugte Verschlüsselungsverfahren) bekomme ich die folgende exception:

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 von einem server, wird dieses problem veranschaulicht, ist die Blende.esper.net:6697 (dies ist ein IRC-server). Ein Beispiel für einen server, der nicht nachweisen das problem ist kornbluth.freenode.net:6697. [Nicht überraschend, alle Server auf jedem Netzwerk teilen die gleiche entsprechende Verhalten.]

Mein code (die, wie erwähnt funktioniert bei der Verbindung zu einigen SSL-Server):

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

Ist es, die letzten startHandshake, dass die Ausnahme ausgelöst. Und ja, es gibt einige Magische Los mit den "trustAllCerts'; code Kräfte, die das SSL-system ist nicht überprüfen certs. (Also... nicht ein cert-problem.)

Offensichtlich eine Möglichkeit ist, dass esper-server ist falsch konfiguriert, aber ich suchte und nicht finden irgendwelche anderen Hinweise, um Menschen, die Probleme mit esper SSL-ports, und "openssl" eine Verbindung zu (siehe unten). Also ich wundere mich, wenn dies ist eine Einschränkung von Java-Standard-SSL-Unterstützung oder so etwas. Irgendwelche Vorschläge?

Hier ist, was passiert, wenn ich eine Verbindung zu aperture.esper.net 6697 mit 'openssl' von der Kommandozeile:

~ $ 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, nach allem, was er tut, erfolgreich eine Verbindung herstellen, das ist mehr, als man sagen kann, für meine Java-app.

Sollte es relevant sein, ich bin mit OS X 10.6.8 Java version 1.6.0_26.

Der Grund scheint dies zu sein: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive). Keine Ahnung, welche Größe gesendet wurde, durch den server hier, und was die Spezifikation sagt über diese.
Tatsächlich können Sie sehen, die Größe, die der server verwendet in der openssl Ausgang in der Frage: "Cipher is DHE-RSA-AES256-SHA, Server public key is 2048 bit". Und 2048 > 1024 :-).
nicht genau. Server public key (size) war, und ist, der Schlüssel in der cert. s_client im Jahr 2011 nicht zeigen, ephemeren Schlüssel, 1.0.2 im Jahr 2015 und bis nicht, wie Server Temp Key mehrere Zeilen höher. Obwohl ein guter server meistens machen die DHE-Größe wie RSA-auth Größe.

InformationsquelleAutor sam | 2011-07-27

Schreibe einen Kommentar