I was investigating how to upgrade the certificate used by my mqweb server from RSA to the new, improved, Elliptic Curve, and wondered how to make it most secure.
At first I thought the answer to the question was yes, then I changed my mind to no, then I changed to yes, and now I think you should do something else!
The short answer is you should not specify which cipher specs to use, but you may considering saying which ones not to use by overriding java.security features.
SSL and TLS Deployment Best Practices covers many good topics.
The first part of the TLS handshake
- The client sends a list of the cipher suites it supports to the server
- The serve has its own list (which you can influence)
- The server takes each cipher suite in turn from the client list, and selects the first one which is in the server’s list and matches the server’s certificate
- If the server is using an RSA certificate, then cipher suites with TLS_…RSA_WITH… are used. With Elliptic Curve certificates then TLS_….ECDSA_WITH… are used.
When using Chrome to talk to my java server the certificate suites sent up were
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, strong
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 strong
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 very strong
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 strong
- …
- SSL_RSA_WITH_3DES_EDE_CBC_SHA weak
These go from strong to weak. Certificates with 3DES or _SHA are considered too weak to use.
My java server had the following cipher suites
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
- TLS_RSA_WITH_AES_256_CBC_SHA256
- TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
- TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
- TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
- ….
And the final cipher suite chosen was
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 – top of the list from the client and 29th in the list in the server – not the strongest certificate in the list which was a surprise.
Specifying a server cipher suite.
You can specify the list of cipher suites used by the server using the java property -Djdk.tls.server.cipherSuites=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,…
So yes; you can specify a list of cipher specs, and the order, and so put the “strongest first”.
I then asked myself is the default one TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 any better than the “best one” TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384?
Bulk data encryption.
Looking on the internet, there is a general feeling that there is no significant difference between AES_128 and AES_256. If quantum computers become a reality, then there may be benefits of AES_256, but then the whole of the encryption world will have changed.
AES…GCM is better than AES…CBC. The difference between them is not so clear. GCM is considered better than CBC, it can run on pipeline processors, but may use more CPU overall. Both have weaknesses, but different weaknesses.
Hashing algorithm
I looked at the hashing algorithm, again there was not much difference between SHA256, SHA 384 and SHA512.
I did some evaluation on the use of SHA256 and SHA512 on my laptop using the command openssl speed sha256 sha512. This hashes different sized buffers and calculates bytes processed per second.
type 16 bytes 64 bytes 256 bytes 1024 bytes 16384 bytes sha256 70348.86k 158677.42k 297724.76k 370884.61k 400878.25k sha512 49354.44k 195907.78k 341598.21k 507424.77k 597409.79k
So we can see with very small buffers SHA 256 could do 70 MB/second, and SHA512 could only do 49 MB/second, but with bigger buffers SHA256 did 40MB/second, and SHA512 did 59 MB/second
It looks like there is no significant difference between them.
Note: when they upgraded SHA256 to SHA512 they improved the algorithm as well as the number of iterations. This applies to other algorithms as well.
Overall the default TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 is as good as the “best one” TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, and so there was no advantage in specifying a cipher suite.
Other advantages of not specifiying a cipher suite
Last year you may have specified the then best cipher suite. This year there are new, better, cipher suites which are the default. If you specified the cipher suite you will use last year’s suite.
When your web server supports TLSv1.3 ( dependent on java 11) it will use a different set of cipher suites. By not specifying a cipher suite name, the migration will be easier. Today browsers already support TLS v1.3 and send up a mixture of cipher suites for TLSv1.2 and TLS v1.3 as part of the TLS handshake.
Do not specify the cipher suite – specify what you do not want.
You can specify security information to java using a java.security file. See here. You can override this file using a system parameter like -Djava.security.properties=/home/colinpaice/eclipse-workspace-C/sslJava/bin/serverdisabled.properties.
In this file you can specify
jdk.tls.disabledAlgorithms=…
jdk.certpath.disabledAlgorithms= …
You specify what do you not want.
The defaults are
- jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
- jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024,EC keySize < 224, 3DES_EDE_CBC
You could specify RSA keySize < 2048, so any cipher suites and certificate using an RSA key size of under 2048 would not be allowed.