8

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:

ciphers="TLS_ECDHE_RSA_WITH_RC4_128_SHA,
         TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
         TLS_ECDH_RSA_WITH_RC4_128_SHA,
         TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
         TLS_RSA_WITH_RC4_128_SHA,
         TLS_RSA_WITH_RC4_128_MD5,
         TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
         TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
         TLS_RSA_WITH_AES_256_CBC_SHA,
         TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
         TLS_RSA_WITH_AES_128_CBC_SHA"

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.

4 Answers 4

4

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:
sun.security.ssl.ServerHandshaker
sun.security.ssl.CipherSuite

On ServerHandshaker,
"private void chooseCipherSuite(ClientHello mesg)"
http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-sun/security/sun/security/ssl/ServerHandshaker.java.htm

/*
 * 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) {
            continue;
        }
        if (doClientAuth == SSLEngineImpl.clauth_required) {
            if ((suite.keyExchange == K_DH_ANON) || (suite.keyExchange == K_ECDH_ANON)) {
                continue;
            }
        }
        if (trySetCipherSuite(suite) == false) {
            continue;
        }
        return;
    }
    fatalSE(Alerts.alert_handshake_failure,
                "no cipher suites in common");
}

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

1
4

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.

Update 2022-09-22

A lot of things have changed since this question was first asked back in 2011 about Tomcat 6 or 7 running on probably Java 6, 7, or 8. All reasonably recent versions of both Java and Tomcat can do what you want, just read the appropriate documentation.

5
  • Actually the default for useServerCipherSuitesOrder is based on the underlying JSSE implementation. With tomcat 9 the setting was changed to honorCipherOrder with useServerCipherSuitesOrder being an alias for the new setting and the default changed to false. tomcat.apache.org/tomcat-9.0-doc/config/http.html
    – dpr
    Sep 22, 2022 at 19:47
  • 1
    The current (Tomcat 8.5 and later) default is based upon what Tomcat says it is. There is no fall-back to whatever JSSE thinks is a good idea; Tomcat will always either honor the server's cipher ordering or not. That setting was changed from useServerCipherSuitesOrder -> honorCipherOrder in Tomcat 8.5 when <SSLHostConfig> was introduced. The old name is still used on the <Connector> for backward-compatibility. For completeness, the BIO connector was also dropped and a whopping 4 newer major versions are available from Apache since this answer was originally written. Sep 22, 2022 at 20:20
  • Good answer for cipher-order in general, but for BEAST as stated in the Q: both JSSE and OpenSSL (and also browsers) back in 2012 implemented 1/n or 0/n fragmentation as a better fix to BEAST than RC4, and in subsequent years both TLSv1.0 and all RC4 suites (in any protocol) have become obsolete so that in 2022 both OpenSSL and JSSE, and nearly everything else too, reject both. Sep 23, 2022 at 5:47
  • You’re right the fallback was removed with 8.5 already and the default was set to false (leave it to the client to decide which cipher to use) with introduction of the SSLHostConfig element. Thanks for clarification!
    – dpr
    Sep 23, 2022 at 5:49
  • Yes, I have some familiarity with Tomcat 8.5. ;) Sep 25, 2022 at 19:54
1

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?

7
  • 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, 2011 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, 2011 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, 2011 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, 2011 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]". Nov 13, 2014 at 19:14
1

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.

0

You must log in to answer this question.