Kiedy nawiązuję połączenie SSL z niektórymi serwerami IRC (ale nie z innymi - prawdopodobnie ze względu na preferowaną metodę szyfrowania serwera) pojawia się następujący wyjątek:
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
Ostateczna przyczyna:
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
Przykładem serwera, który demonstruje ten problem jest aperture.esper.net:6697 (to jest serwer IRC). Przykładem serwera, który nie demonstruje problemu, jest kornbluth.freenode.net:6697. [Nic dziwnego, że wszystkie serwery w każdej sieci zachowują się tak samo.]
Mój kod (który, jak wspomniano, działa podczas łączenia się z niektórymi serwerami SSL) to:
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();
To ostatni startHandshake rzuca wyjątek. I tak, z „trustAllCerts” dzieje się jakaś magia; ten kod wymusza na systemie SSL, aby nie weryfikował certyfikatów. (Więc ... nie jest to pewien problem.)
Oczywiście jedną z możliwości jest to, że serwer espera jest źle skonfigurowany, ale przeszukałem i nie znalazłem żadnych innych odniesień do osób mających problemy z portami SSL espera i łączy się z nim „openssl” (patrz poniżej). Zastanawiam się więc, czy to jest ograniczenie domyślnej obsługi SSL w Javie, czy coś. Jakieś sugestie?
Oto, co się dzieje, gdy łączę się z aperture.esper.net 6697 za pomocą „openssl” z wiersza poleceń:
~ $ 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)
---
Jak już wspomniano, po tym wszystkim łączy się pomyślnie, co jest czymś więcej niż możesz powiedzieć o mojej aplikacji Java.
Jeśli ma to znaczenie, używam OS X 10.6.8, Java w wersji 1.6.0_26.
openssl
wyjściowych można zobaczyć w pytaniu: „Szyfr to DHE-RSA-AES256-SHA, klucz publiczny serwera to 2048 bitów”. I 2048> 1024 :-).
Server public key (size)
był i jest kluczem w cert. s_client
w 2011 roku w ogóle nie pokazał efemerycznego klucza; 1.0.2 w 2015 r. I Server Temp Key
nowsze działa tak samo, jak kilka linii wyżej. Chociaż dobry serwer zwykle powinien mieć taki sam rozmiar DHE jak rozmiar uwierzytelniania RSA.
Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
. Nie mam pojęcia, jaki rozmiar przesłał tutaj serwer i co mówi o tym specyfikacja.