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).
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 |
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.