0

I am developing a REST server that runs with Jersey on Glassfish, and I want to make it run on HTTPS on localhost.

I have found many tutorials for generating a CA cert, others for generating .cer / .crt / .key / .csr / ... files, others for generating a jks keystore.

But they do not answer my (very basic) question: how to generate a self signed certificate and use it in my app that runs on Glassfish, on localhost? From scratch to the integration for a real usage, without any prerequiresite having a crt, a jks or any other file.

(For information I use Linux)

Thanks

EDIT: I have finally created a certificate with the following commands

openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
openssl pkcs12 -export -name localhostServerCert -in localhost.crt -inkey localhost.key -out localhostP12Keystore.p12
keytool -importkeystore -destkeystore localhostKeystore.jks -srckeystore localhostP12Keystore.p12 -srcstoretype pkcs12 -alias localhostServerCert
copy localhostKeystore.jks into /glassfish/domains/domain1/config
keytool -importkeystore -srckeystore localhostKeystore.jks -destkeystore keystore.jks

And I have modified http-listener-2 in the admin console with certificate nickname localhostServerCert, but I got an error page on https://localhost:8181 (ERR_CONNECTION_REFUSED)

EDIT 2 : I think there should be a problem with the certificate, since openssl s_client -showcerts -connect localhost:8181 returns no peer certificate available, No client certificate CA names sent

Romain Guidoux
  • 2,943
  • 4
  • 28
  • 48
  • Have you seen https://sectigo.com/resource-library/install-certificates-glassfish-server tutorial. Glassfish is a java server. Java uses JKS to store ssl keys. You have to generate a key and store it in JKS and then point to it when enabling https. https://docs.oracle.com/cd/E19798-01/821-1841/gjrgy/ – Yan Dec 21 '21 at 14:38
  • @Yan yes this is typically the kind of tutorial I don't like. They don't explain where do crt files come from (addtrustexternalcaroot.crt, XYZRSAAddTrustCA.crt, XYZRSADomainValidationSecureServerCA.crt) – Romain Guidoux Dec 21 '21 at 15:08
  • you don't really need to import root and intermediate CA certificates to your trust store because you are doing local testing and will just approve the connection in the browser when it shows certificate is invalid – Yan Dec 21 '21 at 15:28
  • I think for your purpose you just need to create JKS via `keytool -genkey -alias server-alias -keyalg RSA -keypass changeit -storepass changeit -keystore keystore.jks` and then install it – Yan Dec 21 '21 at 15:30
  • @Yan Well, I have executed your cmd line into the glassfish domain config folder, then I edited the port and alias in the admin console and I replaced s1as by my own alias in domain.xml but it doesn't seem to work (website unaccessible). Moreover concerning the CA certificate, I will also hit my REST endpoints by using Insomnia and a React app. – Romain Guidoux Dec 21 '21 at 16:05
  • I am not familiar with Glassfish not sure why it's it not starting. On the react app side you would have to either disable SSL certification verification(not a good idea and only for local testing), get a real cert (let's encrypt?) or import the cert into the trust store of your computer. Also, do you see error in glassfish logs? Maybe will give you some ideas what's wrong. Might be something wrong with the config. – Yan Dec 21 '21 at 17:12
  • check out this https://stackoverflow.com/questions/6340918/trust-store-vs-key-store-creating-with-keytool post .. maybe will give you a better understanding of keystore vs trust store purpose – Yan Dec 21 '21 at 17:15
  • Depending on which version of GF you are using, take a look at either the Java EE 7 samples at https://github.com/javaee-samples/javaee7-samples/tree/master/servlet/security-clientcert or its Jakarta equivalent at https://github.com/javaee-samples/jakartaee-samples/tree/main/ee7/servlet/security-clientcert – Arjan Tijms Dec 21 '21 at 17:49
  • @Yan I have finally generated and installed a self signed certificate, but `https://localhost:8181` still displays an `ERR_CONNECTION_CLOSED` error. In Glasfish logs there are many warnings indicating certificates expirations, but I read that it's normal (my certificate is not listed here) – Romain Guidoux Dec 22 '21 at 14:21
  • @Yan I think there should be a problem with the certificate, since `openssl s_client -showcerts -connect localhost:8181` returns `no peer certificate available`, `No client certificate CA names sent` :( – Romain Guidoux Dec 22 '21 at 19:36
  • It all make sense. What are the errors on the server side? have you seen this https://www.ssls.com/knowledgebase/how-to-install-an-ssl-certificate-on-glassfish/ .. sorry stupid question :) http-listener-2 is set to port 8181 and TLS enabled .. are there any errors loading the cert.. maybe add the name of JKS in the config – Yan Dec 22 '21 at 20:40
  • @Yan Yes thanks I used this article to install the certificate :) I cannot see any error in the logs. I also tried checking the SSL3 option, and adding the JKS name in the config, but it doesn't change anything – Romain Guidoux Dec 22 '21 at 21:01
  • seems like it should just work. Try to enable `-Djavax.net.debug=SSL` maybe will give you more information about SSL certs and if it loads the JKS. also check the JKS to see the key is there `keytool -list -v -keystore mykeystore.jks` – Yan Dec 22 '21 at 21:22
  • @Yan Thanks, it helped, I got new logs and an error: `http-listener-2(1), fatal error: 40: no cipher suites in common` `javax.net.ssl.SSLHandshakeException: no cipher suites in common`. But I do not understand since there are ciphers in the logs: `Cipher Suites: [Unknown 0x13:0x2, Unknown 0x13:0x3, Unknown 0x13:0x1, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, Unknown 0xcc:0xa9, Unknown 0xcc:0xa8, Unknown 0xcc:0xaa, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, ..., TLS_EMPTY_RENEGOTIATION_INFO_SCSV]` – Romain Guidoux Dec 26 '21 at 20:59

1 Answers1

1

COMMON GOALS

It can be useful to run with SSL locally, and I like to start with real world URLs. This can also help you to think ahead to your production deployment design, which often involves a Private PKI these days, based on a self issued Root CA.

Web and API domains can sometimes be related these days, eg if an API issues secure cookies for the web origin. So for localhost development I first define URLs such as these:

DEVELOPER SETUP

Then add entries such as this to my hosts file:

127.0.0.1 localhost web.mycompany.com api.mycompany.com
:1        localhost

Then, in terms of certificates, I produce these deployable files:

Certificate Filename Usage
Root CA mycompany.ca.pem The root certificate authority that is trusted by the Java runtime
Wildcard Certificate mycompany.ssl.p12 A password protected PKCS12 file deployed with the API

My Development Certificates Repository has an example of how to issue the certs using openssl, including a bash script you can use for your own domains. Essentially this is a Private PKI for a development computer.

CONFIGURING TRUST

You then just need to trust the Root CA in the Java runtime used by Glassfish. Personally I tend to avoid JKS files where possible, since they are specific to Java, whereas PKCS12 files are a more portable concept:

sudo "$JAVA_HOME/bin/keytool" -import -alias mycompanyroot -cacerts -file ~/Desktop/mycompany.ca.pem -storepass changeit -noprompt

FURTHER DEVELOPER SETUP INFO

These resources on a portable way to manage SSL development certs are provided below, which completes the architecture work:

System.setProperty(
  "server.ssl.key-store", 
  configuration.getApi().getSslCertificateFileName());

System.setProperty(
  "server.ssl.key-store-password",
  configuration.getApi().getSslCertificatePassword());

GLASSFISH

If Glassfish based setups mean the API itself does not load the PKCS12 file, then there may be a specific task to import the PKCS12 file. Many systems provide a GUI or API option for loading a PKCS12 file into a keystore. This may result in a command like this being run, which you can do manually if needed:

keytool -importkeystore -srckeystore mycompany.ssl.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype jks -v
Gary Archer
  • 22,534
  • 2
  • 12
  • 24
  • Hi Gary, but loading the root certificate you generate were you able to call the glassfish https with any java program? Because i were struggling on that part and noticed that i had to remove from the root certificate the authority key identifier to make it work. Probably there is some setting in openssl but i took a "shortcut" to generate roots via code: https://github.com/kendarorg/JavaCaCertGenerator what do you think? – Kendar Mar 10 '22 at 22:31