5

I'm trying to install my SSL certificate I acquired for my domain from Comodo but am getting a

SSLHandshakeException: No cipher suites in common

I've read through the multiple questions on this topic but none of the proposed answers have helped me yet.

Comodo provided four certificates:

  • AddTrustExternalCARoot.crt
  • COMODORSAAddTrustCA.crt
  • COMODORSADomainValidationSecureServerCA.crt
  • STAR_example_com.crt

I'm setting up the server in a Dockerfile to isolate the problem from my local development environment:

from google/debian:wheezy
# Server binary and certificates are copied in before this
RUN apt-get update && apt-get install -y openjdk-7-jre
ADD UnlimitedJCEPolicyJDK7.zip /
RUN unzip UnlimitedJCEPolicyJDK7.zip && cp UnlimitedJCEPolicy/*.jar /usr/lib/jvm/java-1.7.0-openjdk-amd64/jre/lib/security/
RUN keytool -import -trustcacerts -alias root -file AddTrustExternalCARoot.crt -keystore /example.com.jks -storepass changeit -noprompt
RUN keytool -import -trustcacerts -alias int-1 -file COMODORSAAddTrustCA.crt -keystore /example.com.jks  -storepass changeit -noprompt
RUN keytool -import -trustcacerts -alias int-2 -file COMODORSADomainValidationSecureServerCA.crt -keystore /example.com.jks  -storepass changeit -noprompt
RUN keytool -import -trustcacerts -alias mykey -file STAR_example_com.crt -keystore /example.com.jks  -storepass changeit -noprompt

Output from keytool commands in Docker:

Step 10 : RUN keytool -import -trustcacerts -alias root -file AddTrustExternalCARoot.crt -keystore /example.com.jks -storepass changeit -noprompt
 ---> Running in 949afa47c891
Certificate was added to keystore
 ---> 1df5ff85c32a
Removing intermediate container 949afa47c891
Step 11 : RUN keytool -import -trustcacerts -alias int-1 -file COMODORSAAddTrustCA.crt -keystore /example.com.jks  -storepass changeit -noprompt
 ---> Running in 6cc802ee61f9
Certificate was added to keystore
 ---> f6eee577e7d5
Removing intermediate container 6cc802ee61f9
Step 12 : RUN keytool -import -trustcacerts -alias int-2 -file COMODORSADomainValidationSecureServerCA.crt -keystore /example.com.jks  -storepass changeit -noprompt
 ---> Running in 22e6bc1e70a6
Certificate was added to keystore
 ---> d7a0472a9e1f
Removing intermediate container 22e6bc1e70a6
Step 13 : RUN keytool -import -trustcacerts -alias mykey -file STAR_example_com.crt -keystore /example.com.jks  -storepass changeit -noprompt
 ---> Running in 9a812b1182ca
Certificate was added to keystore

Comodos instructions say that this last 'Certificate was added to keystore' message should be 'Certificate reply was installed in keystore'. What should I do differently when installing the domain certificate?

The SSL configuration in Spray looks like so:

trait SslConfiguration {
  implicit def sslContext: SSLContext = {
    val password = "changeit"
    val keyStoreResource = "/example.com.jks"

    val keyStore = KeyStore.getInstance("jks")
    keyStore.load(new FileInputStream(keyStoreResource), password.toCharArray)
    val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm)
    keyManagerFactory.init(keyStore, password.toCharArray)
    val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
    trustManagerFactory.init(keyStore)
    val context = SSLContext.getInstance("TLS")

    context.init(keyManagerFactory.getKeyManagers, null, new SecureRandom)
    context
  }

  implicit def sslEngineProvider: ServerSSLEngineProvider = {
    ServerSSLEngineProvider { engine =>
      engine.setEnabledCipherSuites(Array("TLS_RSA_WITH_AES_256_CBC_SHA"))
      engine.setEnabledProtocols(Array("SSLv3", "TLSv1"))
      engine
    }
  }
}

Server Boot:

object Server extends SimpleRoutingApp with SprayJsonSupport with SslConfiguration {
  def apply(config: Configuration, router: ActorRef)(implicit actorSystem: ActorSystem) = {
    val settings = ServerSettings(actorSystem).copy(sslEncryption = true)
    startServer("0.0.0.0", config.notifyPort, serviceActorName = "notify-server", settings = Some(settings)) {
      path("ping") {
        complete("OK")
      }
    }
  }
}

Handshake Debug output:

curl https://localhost:9082/ping

Using SSLEngineImpl.
Using SSLEngineImpl.
Using SSLEngineImpl.
Using SSLEngineImpl.
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
[Raw read]: length = 5
0000: 16 03 01 00 BF                                     .....
[Raw read]: length = 191
0000: 01 00 00 BB 03 03 55 9C   69 B9 0E 94 CA 61 A4 3C  ......U.i....a.<
0010: 95 0B A5 81 B6 BA D4 90   3D 4B 8C 4E BB 35 17 8F  ........=K.N.5..
0020: 19 9E B6 D0 2E BB 00 00   5E 00 FF C0 24 C0 23 C0  ........^...$.#.
0030: 0A C0 09 C0 07 C0 08 C0   28 C0 27 C0 14 C0 13 C0  ........(.'.....
0040: 11 C0 12 C0 26 C0 25 C0   2A C0 29 C0 05 C0 04 C0  ....&.%.*.).....
0050: 02 C0 03 C0 0F C0 0E C0   0C C0 0D 00 3D 00 3C 00  ............=.<.
0060: 2F 00 05 00 04 00 35 00   0A 00 67 00 6B 00 33 00  /.....5...g.k.3.
0070: 39 00 16 00 AF 00 AE 00   8D 00 8C 00 8A 00 8B 00  9...............
0080: B1 00 B0 00 2C 00 3B 01   00 00 34 00 00 00 0E 00  ....,.;...4.....
0090: 0C 00 00 09 6C 6F 63 61   6C 68 6F 73 74 00 0A 00  ....localhost...
00A0: 08 00 06 00 17 00 18 00   19 00 0B 00 02 01 00 00  ................
00B0: 0D 00 0C 00 0A 05 01 04   01 02 01 04 03 02 03     ...............
notify-server-akka.actor.default-dispatcher-6, READ: TLSv1 Handshake, length = 191
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1419536569 bytes = { 14, 148, 202, 97, 164, 60, 149, 11, 165, 129, 182, 186, 212, 144, 61, 75, 140, 78, 187, 53, 23, 143, 25, 158, 182, 208, 46, 187 }
Session ID:  {}
Cipher Suites: [TLS_EMPTY_RENEGOTIATION_INFO_SCSV, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_PSK_WITH_AES_256_CBC_SHA384, TLS_PSK_WITH_AES_128_CBC_SHA256, TLS_PSK_WITH_AES_256_CBC_SHA, TLS_PSK_WITH_AES_128_CBC_SHA, TLS_PSK_WITH_RC4_128_SHA, TLS_PSK_WITH_3DES_EDE_CBC_SHA, TLS_PSK_WITH_NULL_SHA384, TLS_PSK_WITH_NULL_SHA256, TLS_PSK_WITH_NULL_SHA, TLS_RSA_WITH_NULL_SHA256]
Compression Methods:  { 0 }
Extension server_name, server_name: [host_name: localhost]
Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA384withRSA, SHA256withRSA, SHA1withRSA, SHA256withECDSA, SHA1withECDSA
***
[read] MD5 and SHA1 hashes:  len = 191
0000: 01 00 00 BB 03 03 55 9C   69 B9 0E 94 CA 61 A4 3C  ......U.i....a.<
0010: 95 0B A5 81 B6 BA D4 90   3D 4B 8C 4E BB 35 17 8F  ........=K.N.5..
0020: 19 9E B6 D0 2E BB 00 00   5E 00 FF C0 24 C0 23 C0  ........^...$.#.
0030: 0A C0 09 C0 07 C0 08 C0   28 C0 27 C0 14 C0 13 C0  ........(.'.....
0040: 11 C0 12 C0 26 C0 25 C0   2A C0 29 C0 05 C0 04 C0  ....&.%.*.).....
0050: 02 C0 03 C0 0F C0 0E C0   0C C0 0D 00 3D 00 3C 00  ............=.<.
0060: 2F 00 05 00 04 00 35 00   0A 00 67 00 6B 00 33 00  /.....5...g.k.3.
0070: 39 00 16 00 AF 00 AE 00   8D 00 8C 00 8A 00 8B 00  9...............
0080: B1 00 B0 00 2C 00 3B 01   00 00 34 00 00 00 0E 00  ....,.;...4.....
0090: 0C 00 00 09 6C 6F 63 61   6C 68 6F 73 74 00 0A 00  ....localhost...
00A0: 08 00 06 00 17 00 18 00   19 00 0B 00 02 01 00 00  ................
00B0: 0D 00 0C 00 0A 05 01 04   01 02 01 04 03 02 03     ...............
%% Initialized:  [Session-1, SSL_NULL_WITH_NULL_NULL]
notify-server-akka.actor.default-dispatcher-6, fatal error: 40: no cipher suites in common
javax.net.ssl.SSLHandshakeException: no cipher suites in common
%% Invalidated:  [Session-1, SSL_NULL_WITH_NULL_NULL]
notify-server-akka.actor.default-dispatcher-6, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
notify-server-akka.actor.default-dispatcher-6, WRITE: TLSv1.2 Alert, length = 2
notify-server-akka.actor.default-dispatcher-6, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLHandshakeException: no cipher suites in common
[ERROR] [07/08/2015 00:07:22.230] [notify-server-akka.actor.default-dispatcher-6] [akka://notify-server/user/IO-HTTP/listener-0/0] Aborting encrypted connection to 10.0.2.2/10.0.2.2:50790 due to [SSLHandshakeException:no cipher suites in common] -> [SSLHandshakeException:no cipher suites in common]

I've followed Comodos instructions to a tee EXCEPT for the alias setting. I'm not 100% sure if I should be setting the domain alias to 'mykey' or something else. Could this be the problem?

Any help with this problem would be greatly appreciated!

Upio
  • 1,364
  • 1
  • 12
  • 27
  • might be helpful - http://stackoverflow.com/questions/30758303/problems-connecting-via-https-ssl-through-own-java-client – ZhongYu Jul 08 '15 at 00:37
  • My local_policy.jar contains no restrictions on crypto algorithms so unfortunately that doesn't help me. – Upio Jul 08 '15 at 00:47
  • where's the exception thrown? on the client side, or on the server side. – ZhongYu Jul 08 '15 at 00:49
  • Server side. I'm only trying to connect via browser or curl. – Upio Jul 08 '15 at 00:51
  • the default `local_policy.jar` is restricted. so if you haven't, you should replace it. – ZhongYu Jul 08 '15 at 00:53
  • I've just updated the Dockerfile to replace it. But i checked it before doing this and it wasn't restricted. It did add META-INF/ORACLE_J.RSA files. Doesn't work with the change. Same errors. – Upio Jul 08 '15 at 00:54
  • It's odd then to see "Ignoring unsupported cipher suite" in your server log. – ZhongYu Jul 08 '15 at 01:02
  • anyways, why do you config `engine.setEnabledCipherSuites(Array("TLS_RSA_WITH_AES_256_CBC_SHA"))`? why not use the default set of enabled suites? – ZhongYu Jul 08 '15 at 01:03
  • Following sprays recommended example https://github.com/spray/spray/blob/master/examples/spray-can/simple-http-server/src/main/scala/spray/examples/MySslConfiguration.scala#L32 – Upio Jul 08 '15 at 01:07
  • I should mention that i've tried not doing that and all default variations. – Upio Jul 08 '15 at 01:10
  • So it turns out that I hadn't installed the private key in the KeyStore http://stackoverflow.com/questions/17695297/importing-the-private-key-public-certificate-pair-in-the-java-keystore – Upio Jul 08 '15 at 02:08
  • I should note that the spray examples are just examples and not recommendations that follow the latest TLS best practices which now change monthly. We should add a comment to that file that you need to know what you are doing. – jrudolph Jul 08 '15 at 07:36

3 Answers3

4

The problem was resolved when I followed these instructions to install the certificate and private key in the keystore. I was following instructions that assumed this step had already been done.

Community
  • 1
  • 1
Upio
  • 1,364
  • 1
  • 12
  • 27
1

I had the exact same issue and it was due to the Java Cryptography Extension missing. You can download and install it from here http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

Normally the JDK (not the JRE) comes with some libraries already installed.

mericano1
  • 2,914
  • 1
  • 18
  • 25
  • It wasn't this in the end. It had to do with how I was setting up my keystore. I wasn't installing the private key + certificate properly http://stackoverflow.com/questions/17695297/importing-the-private-key-public-certificate-pair-in-the-java-keystore – Upio Jul 08 '15 at 23:43
0

For me this was caused by wrong keystore being in use.

I had two modules in the same application, and another one initialized javax.net.ssl to its liking and the part throwing the Exception listed above got turn only after that.

And once the javax.net.ssl has initialized once, changing the key- and truststore system properties no longer affect anything.

I figured this out by putting -Djavax.net.debug=ssl to the original application server command line call, to make sure the option was set before anyone else got their turn. Then you can see on STDOUT who initializes the stores and with what.

Zds
  • 4,311
  • 2
  • 24
  • 28