A quick guide to do all things certificate related.
Ready to use self signed certificate with SAN extensions.
openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes \
-keyout app.domain.com.key -out app.domain.com.cer \
-subj /C=IN/ST=MH/L=PUN/O=TW/OU=IT/CN=app.domain.com \
-extensions ext \
-config <(cat <<EOF
[req]
distinguished_name=req
[ext]
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=DNS:app.domain.com,DNS:*.domain.com,IP:1.2.3.4
EOF
)
Certificate Signing Request with SAN records which can be sent to a CA for getting signed.
openssl req -newkey rsa:4096 -sha256 -days 365 -nodes \
-keyout app.domain.com.key -out app.domain.com.csr \
-subj /C=IN/ST=MH/L=PUN/O=TW/OU=IT/CN=app.domain.com \
-config <(cat <<EOF
[req]
req_extensions = req_ext
distinguished_name=req
[req_ext]
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=DNS:app.domain.com,DNS:*.domain.com,IP:1.2.3.4
EOF
)
Create a self signed CA certificate
openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes \
-keyout ca.domain.com.key -out ca.domain.com.cer \
-subj /C=IN/ST=MH/L=PUN/O=TW/OU=IT/CN=ca.domain.com \
-extensions ext \
-config <(cat <<EOF
[req]
distinguished_name=req
[ext]
keyUsage=critical,keyCertSign,cRLSign
basicConstraints=critical,CA:true,pathlen:1
subjectAltName=DNS:ca.domain.com
EOF
)
This certificate will act as CA. Keep the CA private key and CA cert safe.
To sign the generated CSR with the created CA using below command.
openssl x509 -req -days 365 -in app.domain.com.csr -out app.domain.com.cer \
-CA ca.domain.com.cer -CAkey ca.domain.com.key -CAcreateserial \
-extensions ext \
-extfile <(cat <<EOF
[ext]
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=DNS:app.domain.com,DNS:*.domain.com,IP:1.2.3.4
EOF
)
please note the fact that you have to supply the extensions again. The extensions requested by CSR are removed from signed cert by default for security reasons.
To keep the extensions in the signed cert, you need to check requested extensions by reading CSR, and then supply them in this format.
Majority of the times it is always necessary to give an application a cert chain containing the cert meant for application and all it's signing authorities.
To create a cert chain in PEM format simply concatenate the PEM format cert files of your signed certificate and the CA that signed the certificate. The resulting file should look as
-----BEGIN CERTIFICATE----- (Your Primary SSL certificate: your_domain_name.cer) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- (Your Intermediate certificate: IntermediateCA.cer) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- (Your Root certificate: RootCA.cer) -----END CERTIFICATE-----
Save the file as .pem
and use it as the certificate provided to your application or stored inside keystore of choice.
Import the ca.domain.com.cer
in the respective application/OS trusted authorities. Methods vary for various applications and operating systems.
Once CA is imported and if your domain name matches the CN in certificate, browsers will display the https endpoint without error.
PKCS12 store type is the industry standard and most flexible, you can create it by importing existing certs or keys.
You cannot create a JKS keystore by adding existing keys/certs to it. You always have to first create a PKCS12 store and convert it into JKS store. Post which it can be freely edited and keys and certs can be added to it.
Private Keys again cannot be exported from JKS, only certs can be. JKS format should therefore only be used when an application demands for it. PKCS12 is altogether a better choice.
Print Cert: openssl x509 -text -noout -in app.domain.com.cer
Print CSR: openssl req -text -noout -in app.domain.com.csr
PKCS12 Keystore: openssl pkcs12 --help
JKS Keystore: keytool --help