title: Why does SSL handshake give 'Could not generate DH keypair' exception?
body: <p>When I make an SSL connection with some IRC servers (but not others - presumably due to the server's preferred encryption method) I get the following exception:</p>
  
  <pre><code>Caused by: java.lang.RuntimeException: Could not generate DH keypair
      at com.sun.net.ssl.internal.ssl.DHCrypt.&lt;init&gt;(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
  </code></pre>
  
  <p>Final cause:</p>
  
  <pre><code>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.&lt;init&gt;(DHCrypt.java:100)
      ... 10 more
  </code></pre>
  
  <p>An example of a server that demonstrates this problem is aperture.esper.net:6697 (this is an IRC server). An example of a server that does not demonstrate the problem is kornbluth.freenode.net:6697. [Not surprisingly, all servers on each network share the same respective behaviour.]</p>
  
  <p>My code (which as noted does work when connecting to some SSL servers) is:</p>
  
  <pre><code>    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();
  </code></pre>
  
  <p>It's that last startHandshake that throws the exception. And yes there is some magic going on with the 'trustAllCerts'; that code forces the SSL system not to validate certs. (So... not a cert problem.)</p>
  
  <p>Obviously one possibility is that esper's server is misconfigured, but I searched and didn't find any other references to people having problems with esper's SSL ports, and 'openssl' connects to it (see below). So I'm wondering if this is a limitation of Java default SSL support, or something. Any suggestions?</p>
  
  <p>Here's what happens when I connect to aperture.esper.net 6697 using 'openssl' from commandline:</p>
  
  <pre><code>~ $ 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)
  ---
  </code></pre>
  
  <p>As noted, after all that, it does connect successfully which is more than you can say for my Java app.</p>
  
  <p>Should it be relevant, I'm using OS X 10.6.8, Java version 1.6.0_26.</p>