3
votes

Maybe I will find help here. I want to enable SSL on Spring Boot application. I have a configuration like:

server: port: 8999 ssl: enabled: true key-store: classpath:keystore.jks key-store-password: mypass key-password: mypass

The problem is my keystore. I've imported *crt file into keystore with alias 'tomcat':

keytool -importcert -file certificate.crt -keystore native.jks -alias tomcat

However, I still can't properly access my rest api. It vomits with error in firefox:

SSL_ERROR_RX_RECORD_TOO_LONG

  • it doesn't work. How can I make proper keystore to make it work? I'm issuing with CA certificate, NOT self-signed. I have files like:

certificate.crt, certificate.p12, certificate.pk, privkey.pem and three files root_ca_1.ca-bundle, root_ca_2.ca-bundle, root_ca_3.ca-bundle

. That's all I have. I'm very fresh with ssl topic, just read some tutorials and tried few keytool commands to make it work. I'd be grateful for help. Thank You in advance.

3
Thank You for reply. However, this tutorial doesn't resolve my problem since it's based on self-signed certificate. I'm desperately searching for clues how can I import CA certificate properly to my keystore.Adam De

3 Answers

5
votes

I just spent the afternoon figuring out this exact problem, so I'll share my process here.

Each of the references below provides instructions on how to generate and use a self-signed certificate. That's not exactly what I'm trying to do, but these each contain some useful background information.

REFERENCES:

I have already purchased a real CA-issued SSL certificate for the *.jimtough.org 'wildcard' domain. I purchased the certificate from http://www.namecheap.com/, but the actual Certificate Authority (CA) is Comodo.

As part of the purchase/activation procedure with the CA, I needed to follow these instructions:

Note that I opted to follow their AWS instructions because I am an AWS user and have an EC2 server readily available with OpenSSL and Java already installed on the server. There are lots of other alternatives to do the same procedure, so search further to find the 'generating a CSR' instructions that are right for you.

At the end of this step, I have the following two files:

  • csr.pem - This is used as part of the SSL cert request/activation process
  • private.key - This is the private key part of my SSL cert, which I will need later to install the cert on my servers. Keep it secret. Keep it safe.

After I completed the purchase and verification procedure for my SSL cert, the CA sent me back a .zip file that contained a .p7b, .crt, and .ca-bundle file.

One of the reference links below explains the difference between these certificate file types:

  • .p7b - This type should be compatible with Java-based applications (PKCS#7 format)
  • .crt - This type should be compatible with most everything else - the link above suggests this is PEM format
  • .ca-bundle - Not sure when to use this - the link above suggests this is PEM format

REFERENCES:

Next I need to figure out how to use the files that I listed above to configure my Spring Boot application for HTTPS.

I will follow the relevant parts of the below tutorials to get what I need:

NOTE: In both tutorials, I will NOT follow their sections on creating a self-signed certificates, since I already possess a real certificate that was issued by a real CA.

The first relevant step in their instructions is to create a new Java keystore. The requirements are:

  • Must have Java installed, so I have access to the 'keytool' utility
  • Must have the 'openssl' utility installed, so I can create a .p12 file using my .key and .p7b files as input

I will use my AWS EC2 Linux server to do this. My server already has the Java/keytool and OpenSSL utilities installed. First I need to use the OpenSSL utility to create a .p12 file that (if I understand correctly) will contain both my private key, and the CA-issue certificate. Second, I need to create a new Java keystore that will contain an imported copy of the .p12 file.

  • openssl pkcs12 -export -out jimtough-dot-org.p12 -name "jimtough-dot-org" -inkey private.key -in __jimtough_org.crt
    • IMPORTANT: You need to provide a password at the 'export password' prompt, otherwise the keytool import in the next step will fail
  • keytool -importkeystore -srckeystore jimtough-dot-org.p12 -srcstoretype PKCS12 -destkeystore jimtough-dot-org-keystore.jks -deststoretype JKS
    • You will need to provide the password you used in the 'openssl' command
    • You will also need to provide a new password for the keystore that you are creating
  • (OPTIONAL) keytool -importkeystore -srckeystore jimtough-dot-org-keystore.jks -destkeystore jimtough-dot-org-keystore.pkcs12 -deststoretype pkcs12
    • I received a warning from 'keytool' about JKS being a proprietary format, and a suggestion that I convert my keystore to PKCS12 format, so I did so with this optional command

Finally, I need to package my newly created Java keystore with my Spring Boot application and configure the application to use it.

REFERENCES:

I referred back to the two Baeldung tutorials above, and was able to get the details I needed to make my Spring Boot (with Spring Security enabled) to work.

I created a new 'keystore' folder under the existing 'src/main/resources', and copied both of my newly created keystore files there (I kept both formats).

I added the block below to my Spring Boot application's application.properties file.

#--------------------------------------------------------------------------------------------------
# SSL CONFIGURATION
# The format used for the keystore. It could be set to JKS in case it is a JKS file
#server.ssl.key-store-type=JKS
server.ssl.key-store-type=PKCS12
# The path to the keystore containing the certificate
#server.ssl.key-store=classpath:keystore/jimtough-dot-org-keystore.jks
server.ssl.key-store=classpath:keystore/jimtough-dot-org-keystore.pkcs12
server.ssl.key-store-password=mykeystorepassword
server.ssl.key-alias=jimtough-dot-org
server.ssl.enabled=true
server.port=8443
#--------------------------------------------------------------------------------------------------

As expected, I get a bunch of warnings from my browser when I attempt to connect to a locally running instance of the Spring Boot application using https://localhost:8443/ as the URL. This happens because the browser correctly identifies the mismatch between 'localhost' and the expected 'jimtough.org' domain that my SSL certificate was created to run on. There shouldn't be any warnings when I deploy the application to a server whose hostname is 'anything.jimtough.org' (or just www.jimtough.org).

That's it! Happy HTTPS'ing!

0
votes

Well, you require few more properties to be added in ssl configuration

server:
ssl:
  key-store: classpath:config/tls/keystore.p12
  key-store-password: password ##this will be your certificate password
  key-store-type: PKCS12
  ciphers: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
  enabled-protocols: TLSv1.2
http2:
  enabled: true

Make sure that the p12 keystore file is present under classpath (src/main/resources) in config/tls

But to generate keystore file use the below openssl command where you will use .crt and .key file to generate .p12 file.

.crt and .key are present under Folder CA and file p12 file will be generated under CA

Please note that you will asked for the certificate password after running the below command

openssl pkcs12 -export -in CA/certificate.crt -inkey CA/certificate.key -name certificate -out CA/certificate.p12

If you want to add this certificate to your local cacert then use the below command

under jre\lib\security

keytool -importcert -noprompt -trustcacerts  -alias ca.certificate  -file   CA/certificate.crt -keystore   cacerts -storepass changeit
-1
votes

Don't use spring-boot for SSL-connections. Let a reverse proxy handle the SSL-termination.
So it is possible, that a tool can automatic renew your certificates (like the certbot).
And you don't need to put a (sercret) private-key to your application.

It is simpler to share your application. A server-admin needs only to setup reverse proxy (or have something familar already in cloud-systems like kubernetes) and can scale up your application.

Benefits

  • Scalable application
  • Simpler spring-setup
  • No secrets in your application
  • Simpler use of application (#cloudSystems)
  • Most reverseProxies are compatible with certbot