6

My company has supplied a Tomcat/MySQL based application to a customer that by default uses http. At the request of the customer I enabled this to use https by creating a self-signed certificate. This worked subject to the expected browser error when using a self-signed cert.

After a pen-test they decided we need to disable some deprecated ssl protocols and and ciphers, so I amended the ssl connector in my tomcat server.xml to look like this:

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
    maxThreads="150" scheme="https" secure="true"
    clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1.2,TLSv1.1" ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_WITH_AES_128_GCM_SHA256"
    keystoreFile="/path/to/keystore/file"
    keystorePass="password" />

This satisfied the pen test and the application continued to work in all three main browsers (Chrome, Firefox and IE). However, the pen test also flagged that we should ideally not be using a self-signed cert so, by following these guides, I created a CSR and got the customer to create a certificate signed to their internal domain (the server could be accessed by a couple of different URLs hence the need to create a CSR with a SAN).

I added the certificate to a new keystore and amended the path in the server.xml file appropriately. Now, when I try to connect I get the following error (this is from Firefox, but all browsers produce a similar error):

Secure Connection Failed

An error occurred during a connection to 172.31.1.36:8443. Cannot communicate securely with peer: no common encryption algorithm(s). Error code: SSL_ERROR_NO_CYPHER_OVERLAP

The page you are trying to view cannot be shown because the authenticity of the received data could not be verified. Please contact the web site owners to inform them of this problem.

My understanding is that the cert does not control what ciphers or protocols should be used so I don't understand why this has happened. Is this an error I've made in producing the CSR or could it be an error the client has made with generating the cert?

-EDIT-

I seem to be getting errors everywhere I turn. If I try to import the key to a keystore I get either this:

cat <keyfile> | openssl  pkcs12 -export -out <keystore>.p12
Enter pass phrase:
unable to load certificates

Or this:

keytool -importkeystore -srckeystore <keyfile> -srcstoretype pkcs12 -destkeystore <keystore>.jks
Enter destination keystore password:
Re-enter new password:
Enter source keystore password:
keytool error: java.io.IOException: toDerInputStream rejects tag type 45

I've got the customer to send me the certificate chain and when I try to import that I get this error:

keytool -import -trustcacerts -alias tomcat -file <certchain>.p7b -keystore <keystorefile>.jks
Enter keystore password:
keytool error: java.lang.Exception: Input not an X.509 certificate

I found some solutions on how to convert the pkcs file to x.509 but then I got other errors, so I'm totally stuck now.

Darren
  • 331
  • 3
  • 4
  • 13
  • Did you 'add' the certificate (chain) AND PRIVATE KEY to the Tomcat keystore, or only the certificate? If you `keytool -list` do you have a `PrivateKeyEntry` or only a `trustedCertEntry`? SSL/TLS server must have the private key. Modern Tomcat should be able to use PKCS12 by specifying `keystoreType` otherwise you can convert PKCS12 to JKS using `keytool`. – dave_thompson_085 Mar 09 '17 at 17:14
  • @LightnessRacesinOrbit, Yeah, I saw that question but I didn't think it was relevant as it's kind of the opposite of my problem. – Darren Mar 10 '17 at 09:08
  • @dave_thompson_085, only the trustedCertEntry. My customer is using some kind of web portal to generate the cert and there is an option to download the certificate chain, but I wasn't aware that was needed. I will get that from him too. As for the private key; what private key is this? I haven't generated a key anywhere, only a CSR which he used to get a certificate. Thanks. – Darren Mar 10 '17 at 09:12
  • @LightnessRacesinOrbit, I might be wrong, but the OP in the other question is basically asking "how do I stop Tomcat from using insecure protocols to avoid this error?". I'm asking "I've stopped Tomcat from using insecure protocols but am getting this error, what now?". However, I will have a thorough read of it in case it gives a clue. – Darren Mar 10 '17 at 10:47
  • You couldn't have generated the CSR without the privatekey and [your first link](http://apetec.com/support/generatesan-csr.htm) says 'Generate a private key' then 'Create the CSR' and later 'Package the key ... in a PKCS12'. If you did that, either use the P12 as the keystore or convert it to JKS and use that; see the links at (my) http://stackoverflow.com/a/37423399/2868801 . – dave_thompson_085 Mar 10 '17 at 14:15
  • @dave_thompson_085, you're right, I did generate a key. My bad. This is well out of my experience and knowledge and I am drowning in what all the different files and file extensions. I will update the question with some further information as every time I find what might be an answer the command doesn't work. Thanks. – Darren Mar 10 '17 at 15:39
  • 1
    (1) You can't create a P12 from _only_ the key, you must give `openssl pkcs12 -export` the privatekey AND the entity cert, and (preferably) any chain cert; your first link has that correct as do at least 3 of the links I pointed to (2) `keytool -importkeystore` to convert from `-srcstoretype pkcs12` only works if the source IS P12; the privatekey file from `genrsa` (or many other openssl operations) is NOT P12 which is precisely why you use `openssl pkcs12 -export` to _convert_ from the (several) formats normally used by OpenSSL to P12 and _after_ that conversion you have a P12 ... – dave_thompson_085 Mar 10 '17 at 22:28
  • 1
    ... (3) `keytool -importcert` can apply a p7b ONLY to a preexisting privatekey entry, which you don't have; otherwise it creates a trustedcert entry which cannot handle and does not accept a chain. You _could_ create a dummy cert and then a keystore containing the correct privatekey with the dummy cert and then use `-importcert` to replace the dummy cert with a valid chain, but in your situation it's less work to just create the keystore with the correct chain. (When the keypair was _generated by_ Java, then it makes sense to import a newly-issued chain to that keystore.) – dave_thompson_085 Mar 10 '17 at 22:33
  • Thank you so much for your patience and help. The root cause of all my problems was that the certificate provided to me was in DER format, no X.509. Once I realised this and converted the certs to the right format, everything else fell into place. – Darren Mar 13 '17 at 10:15

2 Answers2

1

The root cause of all problems was that the certificate was in the wrong format.

By following the info here I discovered the cert was actually in DER format. I converted it as follows:

openssl x509 -inform der -in certfile.cer -out new_certfile.pem
Darren
  • 331
  • 3
  • 4
  • 13
0

The error message is a bit of a red-herring.

When configuring a MikroTik for Webfig https access, you'll get this error if you just create and use a cert that has not been signed by a CA. When the browser sees an unsigned cert, it will puke the error:

"Error code: SSL_ERROR_NO_CYPHER_OVERLAP"

Don't go down the rabbit hole investigating incompatible cyphers or the like: you just need to sign your certificate with a CA and things will work as expected.

The following is a MikroTik-specific procedure to clear the error.

WARNING:

Do not just cut-n-paste: Please replace my placeholders with sensible values ;-)

  • "CAyourDomain": replace "yourDomain with your organization's domain
  • "state": specify a county for those residing outside the USA
  • "subject-alt-name": specify PUBLIC IP of router
  • "ca-crl-host": again, specify PUBLIC IP of router
  • CA "key-size": Note that using "4096" can max CPU and hang thinly provisioned models when signing
  • Tweak the other params as required

Create CA:

/certificate add name=CAyourDomain-template common-name=CAyourDomain country=GB days-valid=3650 key-size=4096 locality="Your City" organization="Your Organization" state=Hertfordshire trusted=yes unit="Technical Services" subject-alt-name="IP:XXX.XXX.XXX.XXX" key-usage=digital-signature,key-cert-sign,crl-sign;

/certificate sign CAyourDomain-template ca-crl-host="XXX.XXX.XXX.XXX" name=CAyourDomain

Create Certificate:

/certificate add name=webfig-template common-name="webfig" country=GB days-valid=3650 key-size=4096 locality="Your City" organization="Your Organization" state=Hertfordshire trusted=yes unit="Technical Services" subject-alt-name="IP:XXX.XXX.XXX.XXX" key-usage=digital-signature,key-encipherment,data-encipherment,tls-server,tls-client;

/certificate sign webfig-template ca=CAyourDomain name=webfig

/certificate set webfig trusted=yes

Specify the Cert:

Now that "webfig" cert has been signed by a CA, you finally need to specify it here to use it:

"IP" > "Services" and enable "www-ssl" and specify "webfig" cert created & subnet HTTPS access is to be allowed from

F1Linux
  • 355
  • 5
  • 12