With the recent buzz about the SSL BEAST vulnerability I wanted to try to improve the security of an SSL protected web site that is based on Tomcat 6. To that end, I tried the google approach of giving non Cipher Block Chaining (CBC) ciphers priority in my Tomcat server.xml file in the HTTP connector declaration:


But Tomcat does not appear to use the order of the ciphers, but instead seems to select the best cipher based on key strength. Also SSL Labs indicates that my site does not show a cipher preference, whereas google.com does. I do not want to remove the 256 bit CBC ciphers in order to use the 128 bit RC4 cipher for fear of SSL incompatibilities. I am guessing that the cipher selection is done at the Java JSSE layer and not in Tomcat.

Does anyone know of a simple way to customize the priority/order of the SSL ciphers with the standard Tomcat HTTP connector? Is there a way to achieve this using a simple custom java class? Does the Tomcat APR connector and some openSSL configuration option offer an alternative. Is there some other simple way to do this?

Note that I realize that this attack requires cross site scripting or some other similar vulnerability, and so is not that serious (for my site). However, if there are easy steps to mitigate this attack, I will take them. Also, I do not want to introduce an Apache front end (assuming there is a way to do this in Apache) because of the extra complexity and therefor risk.


I have the same issue. It seems that we can't do what we want.
The Sun(Oracle) Java SSL implementation checks only the client side cipher suite order(priorities) and ignores the server side.

Related classes are:

On ServerHandshaker,
"private void chooseCipherSuite(ClientHello mesg)"

 * Choose cipher suite from among those supported by client. Sets
 * the cipherSuite and keyExchange variables.
private void chooseCipherSuite(ClientHello mesg) throws IOException {
    for (CipherSuite suite : mesg.getCipherSuites().collection()) {
        if (isEnabled(suite) == false) {
        if (doClientAuth == SSLEngineImpl.clauth_required) {
            if ((suite.keyExchange == K_DH_ANON) || (suite.keyExchange == K_ECDH_ANON)) {
        if (trySetCipherSuite(suite) == false) {
                "no cipher suites in common");

We can see that it itelates cipher suites in the client hello message and chooses cipher suite.


For native/APR/OpenSSL connectors

As of Tomcat 6.0.37/7.0.30/8.0.x, the native/APR/OpenSSL-based connector supports the SSLHonorCipherOrder configuration setting which allows the server to have a specified order in which ciphers are chosen. That ordering is up to you and isn't based upon fuzzy definitions like "strength", since a high-bit cipher can be worse than a lower-bit cipher in certain situations.

For Java-based connectors (BIO, NIO, NIO2)

Tomcat 8.0.21 and later on Java 8 and later will use the server's preferred cipher-suite order if useServerCipherSuitesOrder is set to "true" (the default) for Java-based connectors.

Tomcat 7.0.60 and later on Java 8 and later will use the server's preferred cipher-suite order if useServerCipherSuitesOrder is set to "true" (the default) for Java-based connectors.

Tomcat 6 never had this capability for Java-based connectors; server-preferred ordering of cipher suites on Tomcat 6 will require the use of the APR/native connector.


During handshake the client sends the prefered cipher suites and the server chooses the strongest that both can support.
I am not sure what ordering you expect.

Also SSL Labs indicates that my site does not show a cipher preference, whereas google.com does

I can not understand what you mean here.
What exactly is the complaint? That from the enabled ciphers, Tomcat chose a less week than it supposed to?

  • Yes, the server picks the cipher. However, Tomcat is picking the cipher based on key strength only. I want to pick a non-CBC cipher first then the highest key strength. I mentioned the SSL Labs feedback as a note, not as a complaint. – user967708 Sep 27 '11 at 20:11
  • I do not think that the preference is configurable (but I am not 100% sure).Here docs.huihoo.com/java/javase/7/technotes/guides/security/… it mentions the preference order by Java.I believe Tomcat uses that. BTW I still do not understand the SSLLabs feedback – user76678 Sep 27 '11 at 20:31
  • I did previously look at the Java 6 version of the link you gave, but it indicated the RC4 ciphers had priority (contrary to my results). Also, as you say, I could not find anything in any of the java docs I looked at about controlling the order. – user967708 Sep 27 '11 at 21:26
  • I don't know how the SSL Labs site decides that a site has a cipher preference, but it indicated google had a preference for certain ciphers. Since it indicated my Tomcat site did not show a preference, it might indicate Tomcat or JSSE randomly chooses between ciphers of the same key strength, but I don't know for sure. I am beginning to think the way to figure this out is hunt down the source and maybe it is not worth the trouble. – user967708 Sep 27 '11 at 21:26
  • 1
    FWIW, SSLLabs can detect you have a cipher preference by sending a several client "hello" messages with different cipher orders specified and see which one the server chooses. If the server always chooses the first cipher the client offered, then the server does not have "a preference [for overriding the client's cipher preference]". – Christopher Schultz Nov 13 '14 at 19:14

I don't believe you can order them by preference and once you get rid of the CBC ones, there's an awfully short list of cipher options available! However, most clients are going to connect at RC4-128 any way--at least that's what all my server logs indicate when I feel like turning that logging option on.

Using the OpenSSL connector, you get the option of using a more concise syntax for allowing or disallowing certain ciphers but no options for setting cipher order or even preferred cipher.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy