0

I've setup a Spring Framework 5 project working very well so far. Needed to enable HTTPS for some functionality so followed a tutorial. Currently generated the certificate and key on the server with the following command:

keytool -genkeypair -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 365000

I've then imported this keystore into my resources folder and used the following properties:

server.ssl.key-store= classpath:keystore.p12
server.ssl.key-store-password= myPassword
server.ssl.key-store-type= PKCS12
server.ssl.key-alias= tomcat
server.port= 8444

I've also setup a redirect from HTTP to HTTPS with the following configuration:

@Bean
public ServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
        @Override
        protected void postProcessContext(Context context) {
            SecurityConstraint securityConstraint = new SecurityConstraint();
            securityConstraint.setUserConstraint("CONFIDENTIAL");
            SecurityCollection collection = new SecurityCollection();
            collection.addPattern("/*");
            securityConstraint.addCollection(collection);
            context.addConstraint(securityConstraint);
        }
    };
    tomcat.addAdditionalTomcatConnectors(redirectConnector());
    return tomcat;
}

private Connector redirectConnector() {
    Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
    connector.setScheme("http");
    connector.setPort(8182);
    connector.setSecure(false);
    connector.setRedirectPort(8444);
    return connector;
}

When running locally from my IDE or by running the compiled .jar it works fine. However when I try to run it on my server (a locally running Synology NAS that previously worked fine) I get errors when trying to reach the address (https://192.168.10.10:8444) with the following error on Firefox: SSL_ERROR_NO_CYPHER_OVERLAP and on chrome ERR_SSL_VERSION_OR_CIPHER_MISMATCH. I've looked for answers but I have not found any solutions that changed the outcome of this problem.

Available JDK CIPHERs on the server:

Default Cipher
        SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
*       SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
        SSL_DHE_DSS_WITH_DES_CBC_SHA
        SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
*       SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
        SSL_DHE_RSA_WITH_DES_CBC_SHA
        SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
        SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
        SSL_DH_anon_WITH_DES_CBC_SHA
        SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
*       SSL_RSA_WITH_3DES_EDE_CBC_SHA
        SSL_RSA_WITH_DES_CBC_SHA
        SSL_RSA_WITH_NULL_MD5
        SSL_RSA_WITH_NULL_SHA
*       TLS_DHE_DSS_WITH_AES_128_CBC_SHA
*       TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
*       TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
*       TLS_DHE_DSS_WITH_AES_256_CBC_SHA
*       TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
*       TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
*       TLS_DHE_RSA_WITH_AES_128_CBC_SHA
*       TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
*       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
*       TLS_DHE_RSA_WITH_AES_256_CBC_SHA
*       TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
*       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
        TLS_DH_anon_WITH_AES_128_CBC_SHA
        TLS_DH_anon_WITH_AES_128_CBC_SHA256
        TLS_DH_anon_WITH_AES_128_GCM_SHA256
        TLS_DH_anon_WITH_AES_256_CBC_SHA
        TLS_DH_anon_WITH_AES_256_CBC_SHA256
        TLS_DH_anon_WITH_AES_256_GCM_SHA384
*       TLS_EMPTY_RENEGOTIATION_INFO_SCSV
        TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5
        TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA
        TLS_KRB5_WITH_3DES_EDE_CBC_MD5
        TLS_KRB5_WITH_3DES_EDE_CBC_SHA
        TLS_KRB5_WITH_DES_CBC_MD5
        TLS_KRB5_WITH_DES_CBC_SHA
*       TLS_RSA_WITH_AES_128_CBC_SHA
*       TLS_RSA_WITH_AES_128_CBC_SHA256
*       TLS_RSA_WITH_AES_128_GCM_SHA256
*       TLS_RSA_WITH_AES_256_CBC_SHA
*       TLS_RSA_WITH_AES_256_CBC_SHA256
*       TLS_RSA_WITH_AES_256_GCM_SHA384
        TLS_RSA_WITH_NULL_SHA256

My openSSL s_client connect output:

No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: DH, 1024 bits
---
SSL handshake has read 1601 bytes and written 505 bytes
Verification error: self signed certificate
---
New, TLSv1.2, Cipher is DHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES256-GCM-SHA384
    Session-ID: 5B9B776C430F2AEF917BAE78C14F78CDC6DB2F0ED7284E66EFAF9688319F46B2
    Session-ID-ctx:
    Master-Key: FBA675AEDE7EB03926991415E6760249DE82E4967EC7A724D04C1D8FEFC2C3CC37DFC84ACD29607CAF88775EBBD6E519
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1536915308
    Timeout   : 7200 (sec)
    Verify return code: 18 (self signed certificate)
    Extended master secret: no
---
Mineral
  • 197
  • 1
  • 1
  • 10

2 Answers2

1

Old question, but I had same problem. Synology station uses old JDK (1.8.0_161). After update to latest 1.8 (1.8.0_202-b08) everything works just fine.

cecan89
  • 245
  • 1
  • 2
  • 10
0

A typical error could be that your *.p12 file will not be packed into the deployed artifact.

Have you checked that your jar contains it?

m4gic
  • 1,461
  • 12
  • 19
  • yes it's located in the jar. (\BOOT-INF\classes\keystore.p12) – Mineral Sep 11 '18 at 10:27
  • I wrote an [answer](https://stackoverflow.com/questions/52084431/java-remote-host-closed-connection-during-handshake-using-bittrex-http-api/52086781#52086781) how one can debug SSL problems, maybe you have to do deeper investigation :( – m4gic Sep 11 '18 at 10:34
  • I've added a list of available CIPHERs on the server to the original post. As far as I understand the client and server negotiate the best option both have available, with this list I'm pretty certain that modern browsers such as chrome and firefox can find a mutual one? I'm not that knowledged on this matter so could be wrong of course! – Mineral Sep 11 '18 at 12:04
  • What you should do is to use [SSLPoke](https://gist.github.com/4ndrej/4547029) on the server using the JDK your application server use. If it could connect, your app will be able to connect too. [This](https://blogs.oracle.com/java-platform-group/diagnosing-tls,-ssl,-and-https) link could be useful too, especially the Java version-supported TLS protocol versions table. – m4gic Sep 11 '18 at 12:33
  • Btw, the list you have added belongs to the JDK of your application server, you have to examine the connection too (the ssl debug btw should show what is the problem, hint: if you use it, redirect the stdout of the SSLPoke/java app, it can be huge). – m4gic Sep 11 '18 at 12:37
  • I'm using JDK 8, so no problems with supported TSL protocol. I'm struggling to get your SSL Debug to work. I ran my server application with it (java -jar serverapp.jar -Djavax.net.debug=all > output.txt) but I didn't get any additional prints visible) – Mineral Sep 14 '18 at 09:08
  • I also tried using SSLPoke but I'm also strugging with that sorry :) I ran the openssl command (from a computer that i'm trying to connect to the website from) and got proper output (see first post) but when running the keystore command I got the following error: `keytool -import -alias ccds -keystore 'C:\Program Files\Java\jre-9.0.4\lib\security\cacerts'` `KEYUPDATE` `32:error:1420310A:SSL routines:SSL_key_update:wrong ssl version:ssl\ssl_lib.c:2085:)` – Mineral Sep 14 '18 at 09:09
  • You have used wrong attrib order: (java -Djavax.net.debug=all -jar serverapp.jar> output.txt – m4gic Sep 14 '18 at 09:09
  • I don't see your keytool -import... command what you are trying to import – m4gic Sep 14 '18 at 09:13
  • However in case of JDK9, it seems you have to [convert your PKCS12 keystore to JKS](https://stackoverflow.com/questions/45041311/keystore-does-not-work-on-java-9). – m4gic Sep 14 '18 at 09:21
  • I ran `keytool -import -alias ccds -keystore 'C:\Program Files\Java\jre-9.0.4\lib\security\cacerts'` from within the openssl command line after doing the OpenSSL command. This gave me the error posted above. Thank you for the SSLDebug! I now correctly get the debug output. When trying to attempt a connection i get the following output: https://pastebin.com/Bg9ZT1Mt. This seems to indicate still no common Cipher is found to use? During startup, the server application also gave the following output from debug: https://pastebin.com/deCDBZfJ. Not sure if this is of importance. – Mineral Sep 14 '18 at 09:23
  • I noticed now that I am using JDK9 on my development computer but JRE8 on my server. I did however generate my key on the server with JRE8. And I am compiling with target JRE-level 8. So Not sure if it could be related to the issue? Will try the conversion of my keystore. Just in case it helps. – Mineral Sep 14 '18 at 09:29
  • I have now switched my development JDK to version 8 to match the server. I have tried using both JKS and PKCS12 keystore's. But all errors and logs remain the exact same as before :( – Mineral Sep 14 '18 at 10:28
  • I have some good news: in Java8 TLSv1.2 is enabled by default, and the DHE-RSA-AES256-GCM-SHA384 cipher is supported too. From now I think only the server cert is missing from your client's keystore. You should give portecle a try, it can [examine a tls connection](http://portecle.sourceforge.net/examine-tls.html) and can export its certficate. You can [import](http://portecle.sourceforge.net/import-trusted-cert.html) this cert to any selected keystore by using it. – m4gic Sep 14 '18 at 11:39
  • What java version do you use exactly? Do you use the standard sslsocketfactory (and the rest of these sort of classes)? Do you installed the [JCE extension](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) maybe the applied GCM algo requires it? – m4gic Sep 14 '18 at 11:48