LetsEncrypt cert as p12 fails instanceof CertEntry test in Spring Boot - spring-boot

I used LetsEncrypt's certbot to generate the cert and key pems:
sudo certbot certonly -a standalone -d footeware.ca
...and converted them to a p12:
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat -CAfile chain.pem -caname root
I moved the p12 to my development machine into my eclipse project's resources folder.
When I start the application and debug thru sun.security.pkcs12.PKCS12KeyStore#engineIsCertificateEntry, it finds the aliased entry but states it's not an instanceof sun.security.pkcs12.PKCS12KeyStore.CertEntry but rather a sun.security.pkcs12.PKCS12KeyStore$PrivateKeyEntry and so it fails with:
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
keytool -list on the p12:
Alias name: tomcat
Creation date: Jan. 3, 2022
Entry type: PrivateKeyEntry
Certificate chain length: 3
Certificate[1]:
Owner: CN=footeware.ca
Issuer: CN=R3, O=Let's Encrypt, C=US
What have I done wrong? Should the PrivateKeyEntry be something else?

Thanks #Saif for that link.
I did:
sudo update-ca-certificates -f
sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure
...and used my original keystore.p12 (seems there was nothing wrong with it).
The solution was to change my application.properties' values to:
server.ssl.trust-store=file:/etc/ssl/certs/java/cacerts
server.ssl.trust-store-password=changeit
server.ssl.trust-store-type=JKS
I had been setting those properties to the keystore.p12 thinking they were one and the same (noob).
I deployed and started the appication jar, set my router to forward 443 to my server#8443 (instead of 80 to 8090 as it was) and I'm in with a happy https indicator!
Now I just have to fix the broken css that upgrading bootstrap seems to have caused. Pain that the cert prevents me from using localhost now as it only supports footeware.ca.
Any ideas there?

Related

How to correctly setup TLS/SSL on localhost using http-server?

I'm using http-server to serve my local project through HTTPS. To create the key.pem and the cert.pem files, I followed the documentation:
First, you need to make sure that openssl is installed correctly, and
you have key.pem and cert.pem files. You can generate them using this
command:
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
You will be prompted with a few questions after
entering the command. Use 127.0.0.1 as value for "Common name" if you
want to be able to install the certificate in your OS's root
certificate store or browser so that it is trusted.
This generates a cert-key pair and it will be valid for 3650 days
(about 10 years).
Then you need to run the server with -S for enabling SSL and -C for
your certificate file.
http-server -S -C cert.pem
I used the openssl.exe come with the Git, and installed the generated certificate on Windows (onto the "Trusted Root Certification Authorities" entry). Here is the output after running the server:
Starting up http-server, serving ./ through https
http-server version: 14.1.1
http-server settings:
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none
Available on:
https://10.20.30.232:8080
https://192.168.56.1:8080
https://192.168.1.126:8080
https://127.0.0.1:8080
Hit CTRL-C to stop the server
But, when I access the https://127.0.0.1:8080, I'm encountered with the following error on Google Chrome:
Your connection is not private
...
NET::ERR_CERT_COMMON_NAME_INVALID
Subject: 127.0.0.1
Issuer: 127.0.0.1
...
This server could not prove that it is 127.0.0.1; its security certificate does not specify Subject Alternative Names.
And, the following is the error message Mozilla Firefox presents:
127.0.0.1:8080 uses an invalid security certificate.
The certificate does not come from a trusted source.
Error code: MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY
https://127.0.0.1:8080/
The server uses a certificate with a basic constraints extension identifying it
as a certificate authority. For a properly-issued certificate, this should not
be the case.
HTTP Strict Transport Security: false
HTTP Public Key Pinning: false
So, what am I missing on setting up the HTTPS server to avoid the aforementioned errors?!
Chrome should accept this certificate if you explicitly list 127.0.0.1 as a "Subject Alternative Name" (SAN) of type IP. You can do so by adding -addext "subjectAltName = IP:127.0.0.1" to the openssl command:
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem -addext "subjectAltName = IP:127.0.0.1"
Firefox complains about a very different issue, i.e. that a certificate with a basic constraints extension with CA:TRUE is being used as an end-entity certificate. See also: https://bugzilla.mozilla.org/show_bug.cgi?id=1034124
You could try to generate the certificate without the basic constraints extenstion.
The shortcut solution would be to leverage existing solutions like https://github.com/FiloSottile/mkcert or https://github.com/davewasmer/devcert.

HTTPS for SpringBoot Application on Ubuntu Server (Hosted on STRATO)

i try to develop my SpringBoot Backend Application on STRATO.de
i buyed a ubunutu vServer and runned my spring app via jar.
but backend (http) and frontend (https) cant connect because of the ssl. I created a self signed jks file for my spring boot app and the https works but when i open my backend ip adress and port firstly i get the message "this ist not a secure connection" and i have to accept the certificate. After that everything works fine.
Is there a Option to get a secure connection? i try to use LetsEncrypt CerBot etc. nothing works. The Tutorials are not for the newest Ubuntu version.
Where can i secure my SpringBoot app via HTTPS without a SelfSigned certificate?
Both frontend & backend needs to have https connection for secured communication. Hence it's necessary to use https for your spring-boot application. Self signed jks is only good for development, which is not meant to be used for production.
You may follow these steps:
Install OpenSSL if not available in your server. How to install OpenSSL
Run this command, # openssl req -new -newkey rsa:2048 -nodes -keyout yourkey.key -out yourcsr.csr
Here, yourkey.key = It’s your private key and
yourcsr.csr = Your Certificate Signing Request which needs to send to CA authorities. While creating CSR, it will ask some questions, which will be later required for keystore. Hence, save them properly.
Buy your SSL certificate from your preferable registrant, ie name.com
Send your yourcsr.csr file information to the registrants. Please follow their respective instructions.
Once approved, you will receive two files. yourserver.crt and yourca.crt
# openssl pkcs12 -export -in yourserver.crt -inkey yourkey.key -out yourkeystore.p12 -name somealias -certfile yourca.crt -caname root
It will ask some questions, pls make sure it matches the information that you provided earlier while creating the CSR. It will prompt for password for the keystore. This command will create a keystore named yourkeystore.p12
# keytool -importkeystore -srckeystore yourkeystore.p12 -srcstoretype PKCS12 -destkeystore yourkeystore.jks -deststoretype JKS -deststorepass newkeystorepassword -destkeypass newkeypassword Convert to JKS, if you specifically want to use JKS for spring boot. This command will create a keystore named yourkeystore.jks
Put required information at application.properties.
server.port: 8443
server.ssl.key-store: classpath: yourkeystore.jks
server.ssl.key-store-password: newkeystorepassword
server.ssl.key-store-type: jks
server.ssl.key-alias: somealias
server.ssl.key-password: newkeypassword

Access localhost via HTTPS by Chrome on Ubuntu ("NET::ERR_CERT_AUTHORITY_INVALID")

I want to access localhost via HTTPS by Chrome.
Would you tell me how to solve ?
localhost is building with tomcat in Spring Boot.
I finished to
create self-signed certification(*1)
enable HTTPS on Spring Boot(*2)
import the certificattion by Chrome(*3)
But when I access localhost Chrome display "NET::ERR_CERT_AUTHORITY_INVALID".
my environment:
Ubuntu 18.04
Chrome 79
Spring Boot 2.2.2
Tomcat 9
*1 create self-signed certification:
$ keytool -genkeypair -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650 -ext san=dns:localhost -ext san=ip:127.0.0.1
*2 enable HTTPS on Spring Boot
$ vi src/main/resources/application.properties
server.port=8443↲
server.ssl.enabled=true↲
server.ssl.key-store=keystore.p12↲
server.ssl.key-store-password=password↲
server.ssl.key-password=password↲
server.ssl.key-store-type=PKCS12↲
server.ssl.key-alias=tomcat↲
security.require-ssl=true↲
*3 import the certificattion
$ keytool -exportcert -keystore keystore.p12 -alias tomcat -file keystore.der
(or when I access localhost, export the certificate from Chrome display)
After do, on Manage certificates import keystore.der.(Chrome setting:GUI)
Thanks Regard.
Your certificate is self-signed, so Chrome has no way of verifying that the certificate is valid. Self signed means that you confirm that you are you.
You can either add an exception (preferred way) or import your certificate into Chrome and trust this certificate. If you do the later it means that from now own Chrome will trust this certificate. If you loose it, or share it (eg. with your source code) someone could potentially create a secure site that your browser will no accept as valid no matter what.
Witch Chrome you could also allow invalid certificates for localhost by visiting
chrome://flags/#allow-insecure-localhost
and check "Enable".
Solved
Getting Chrome to accept self-signed localhost certificate
Excerpt from the above link
on Terminal
$ sudo apt-get install libnss3-tools
on Chrome
click the lock icon with an X,
choose Certificate Information
go to Details tab
Click on Export... (save as a file)
on Terminal
$ certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n YOUR_FILE -i YOUR_FILE

How to Enable SSL in Spring boot

I want to use SSL on my server, therefore I have bout an SSL certificate, however the certificate had two parts one of them is the intermediate.
Now how to create the keystore for them?
What I did is the following:
1- chained both certificates and put them in one file.
2- I have usedd the next command to generate the keystore from the (chained certificate)
keytool -import -alias tomcat -file myCertificate.crt -keystore keystore.p12 -storepass password
3- I have add this code into my spring boot:
server.ssl.key-store: C:/Program Files/Java/jdk1.8.0_231/bin/keystore.p12
server.ssl.key-store-password: password
server.ssl.keyStoreType: PKCS12
server.ssl.keyAlias: tomcat
But I am still having the next issue:
'Alias name [tomcat] does not identify a key entry'
From looking into google I have found out that the issu is my keystore is generating my certificate as trustedCertEntry instead of PrivateKeyEntry.
How to fix this and what am I missing?

How do I generate X.509 certificate from key generated by openssl

I've a web server running on an ec2-instance which internally calls a REST server that is built using Spring Boot. Now, I am trying to get this REST server running under SSL. Here's what I've done so far:
1) Created a CSR & a key file using this command
openssl req -newkey rsa:2048 -nodes -keyout mydomain.key -out mydomain.csr
2) Copied 'csr' to get SSL certificate from GoDaddy.
3) Successfully installed the certificate under Nginx on my ec2-instance.
4) When I hit the home page under https, it works. I no longer get 'Not secure' message from the browser.
5) Login fails because it makes a REST call but REST server is not running under SSL so I am trying to get it running under SSL.
6) Ran following commands:
keytool -import -alias mydomain -keystore tomcat.keystore -trustcacerts -file mydomain.com.chained.crt
keytool -import -alias mydomain-key -keystore tomcat.keystore -trustcacerts -file mydomain.key
The previous command gives me an error message:
"keytool error: java.lang.Exception: Input not an X.509 certificate"
But this was the one created in step 1 above & the same file works under Nginx. What am I missing (other than the fact that I know very little about setting up SSLs!)? I need the second command to specify the value of 'server.ssl.keyAlias' in application.properties, I believe.
Not really an answer but overflowed comment.
You don't need to 'generate' an X.509 cert; you already got that from GoDaddy. If (and only if) the SpringBoot server is accessed by the same name(s) as (external) nginx -- which is unclear to me -- you need to convert the pair of private key AND certificate CHAIN from PEM format to a format Java uses. See:
How to import an existing x509 certificate and private key in Java keystore to use in SSL?
How can I set up a letsencrypt SSL certificate and use it in a Spring Boot application?
How to use .key and .crt file in java that generated by openssl?
Importing the private-key/public-certificate pair in the Java KeyStore
maybe Import key and SSL Certificate into java keystore
Thanks #Dave_thompson_085. Following 2 commands did the trick!
openssl pkcs12 -export -in mydomain.com.chained.crt -inkey mydomain.key -out keystore.p12 -name my-alias -caname root
keytool -importkeystore -deststorepass mypassword -destkeypass mypassword -destkeystore keystore.jks -srckeystore keystore.p12 -srcstoretype PKCS12 -srcstorepass mypassword -alias my-alias
and then in the application.properties I specified following properties:
server.port=8443
server.ssl.enabled=true
security.require-ssl=true
server.ssl.key-store=/etc/nginx/ssl/keystore.jks
server.ssl.key-store-password=mypassword
server.ssl.keyStoreType=JKS
server.ssl.keyAlias=my-alias

Resources