HOWTO: Distinguish the Good SSL Ciphers from the Bad in J2SE5

One of the things I am always forgetting with SSL in Java is the relationship between the names of the ssl ciphers and whether or not any particular cipher is weak, medium, strong, etc.  The tables below have been set up to provide a breakdown of each individual cipher included in Sun's JDK1.5, which I hope others will find useful as well.

For PCI Compliance purposes, ciphers marked in red would not be used, either due to weak encryption (<128 bits), null ciphers (which do not encrypt at all), or anonymous authentication (no key exchange between client and server).

 Table 1: SSL Ciphers included in J2SE5
SSL Cipher Encryption Strength Details
 SSL_RSA_WITH_NULL_MD5  0 bit encryption, null cipher
 SSL_RSA_WITH_NULL_SHA  0 bit encryption, null cipher
 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA  40-bit encryption, anonymous auth, export grade
 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5  40-bit encryption, anonymous auth, export grade
 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA  40-bit encryption, export grade
 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA  40-bit encryption, export grade
 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA  40-bit encryption, export grade
 SSL_RSA_EXPORT_WITH_RC4_40_MD5  40-bit encryption, export grade
 SSL_DH_anon_WITH_DES_CBC_SHA  56-bit encryption, anonymous auth
 SSL_DHE_DSS_WITH_DES_CBC_SHA  56-bit encryption
 SSL_RSA_WITH_DES_CBC_SHA  56-bit encryption
 SSL_DHE_RSA_WITH_DES_CBC_SHA  56-bit encryption
 SSL_DH_anon_WITH_RC4_128_MD5  128-bit encryption, anonymous auth
 SSL_RSA_WITH_RC4_128_MD5  128-bit encryption
 SSL_RSA_WITH_RC4_128_SHA  128-bit encryption
 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA  168-bit encryption, anonymous auth
 SSL_RSA_WITH_3DES_EDE_CBC_SHA  168-bit encryption
 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA  168-bit encryption
 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA  168-bit encryption

 Table 2: TLS Ciphers Included in J2SE5
TLS Cipher Encryption Strength Details
 TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5  40-bit encryption, export grade
 TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA  40-bit encryption, export grade
 TLS_KRB5_EXPORT_WITH_RC4_40_MD5  40-bit encryption, export grade
 TLS_KRB5_EXPORT_WITH_RC4_40_SHA  40-bit encryption, export grade
 TLS_KRB5_WITH_DES_CBC_MD5  56 bit encryption
 TLS_KRB5_WITH_DES_CBC_SHA  56 bit encryption
 TLS_DH_anon_WITH_AES_128_CBC_SHA  128 bit encryption, anonymous auth
 TLS_DHE_RSA_WITH_AES_128_CBC_SHA  128 bit encryption
 TLS_DHE_DSS_WITH_AES_128_CBC_SHA  128 bit encryption
 TLS_KRB5_WITH_RC4_128_MD5  128 bit encryption
 TLS_KRB5_WITH_RC4_128_SHA  128 bit encryption
 TLS_RSA_WITH_AES_128_CBC_SHA  128 bit encryption
 TLS_KRB5_WITH_3DES_EDE_CBC_MD5  168 bit encryption
 TLS_KRB5_WITH_3DES_EDE_CBC_SHA  168 bit encryption
 TLS_DH_anon_WITH_AES_256_CBC_SHA  256 bit encryption, anonymous auth
 TLS_DHE_RSA_WITH_AES_256_CBC_SHA  256 bit encryption
 TLS_DHE_DSS_WITH_AES_256_CBC_SHA  256 bit encryption
 TLS_RSA_WITH_AES_256_CBC_SHA  256 bit encryption

Setting them up for use in your java code is with the SetEnabledCipherSuites() method. A code example is below that sets your enabled cipher suites to the "good" ciphers from the table above.

String[] goodCiphers ={"SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_KRB5_WITH_RC4_128_MD5, TLS_KRB5_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_KRB5_WITH_3DES_EDE_CBC_MD5, TLS_KRB5_WITH_3DES_EDE_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA"};
socket.setEnabledCipherSuites(goodCiphers);

The code example above also includes the Kerberos-based ciphers, which you can probably get rid of too because they don't appear to be in widespread use as an authentication option for ssl-encrypted web sites. The updated java code below with the Kerberos ciphers suites removed now looks like this:

String[] goodCiphers ={"SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA"};
socket.setEnabledCipherSuites(goodCiphers);

This is a little bit better and provides a more secure option that will make the guys in Data Security happy.


Creative Commons Attribution-ShareAlike 3.0 Unported