Skip to content

Instantly share code, notes, and snippets.

@winster
Forked from fntlnz/self-signed-certificate-with-custom-ca.md
Last active August 27, 2020 09:44
Show Gist options
  • Save winster/5d41ebe94eabc3195f56091730f01092 to your computer and use it in GitHub Desktop.
Save winster/5d41ebe94eabc3195f56091730f01092 to your computer and use it in GitHub Desktop.
Self Signed Certificate with Custom Root CA
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = .
crl_dir = $dir/crl
database = $dir/db.txt
new_certs_dir = $dir
serial = $dir/serial
crl = $dir/crl.pem
RANDFILE = $dir/.rnd
policy = policy_match
default_days = 365
default_md = sha256
[ policy_match ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[intermediate_ca]
basicConstraints = CA:TRUE
[yourserver]
subjectAltName = DNS:yourserver.local,DNS:yourserver.net,DNS:localhost

Below commands are tested with openssl 1.1.1d 10 Sep 2019 (openssl version)

Create Root CA (both key and certificate in a single command)

openssl req -newkey rsa:2048 -days 825 -nodes \
-x509 -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=root-ca" \
-keyout rootCA.key -out rootCA.crt
  • Windows bash users can prefix MSYS_NO_PATHCONV=1 to avoid errors when using -subj
 MSYS_NO_PATHCONV=1 openssl req ...
  • Verify the contents of rootCA.crt
openssl x509 -in rootCA.crt -text -noout

cat rootCA.key
  • If you want to encrypt the private key, ditch nodes (no des)
openssl req -newkey rsa:2048 -passout pass:"test" -days 825 \
-x509 -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=root-ca" \
-keyout rootCA.key -out rootCA.crt

Google for other ways of giving passwords

Create an intermediate CA (optional)

  • Generate key and certificate signing request (Just remove -x509 from previous command)
openssl req -newkey rsa:2048 -passout pass:"test" \
-subj "/C=US/ST=CA/O=SubOrg, Inc./CN=intermediate-ca" \
-addext "subjectAltName=DNS:suborg.net,DNS:www.suborg.net" \
-keyout intermediateCA.key -out intermediateCA.csr
  • View contents of csr
openssl req -text -noout -verify -in intermediateCA.csr
  • Sign using rootCA (you need to use openssl ca module instead of x509. Atleast I could not find a way to approve basicConstraints using x509. To use ca module, you need to create a conf file and (also a db file, atleast in windows I had to create it)
touch openssl.cnf
touch db.txt
copy contents from gist to openssl.cnf
openssl ca -batch -config openssl.cnf \
-keyfile rootCA.key -passin pass:"test" -cert rootCA.crt \
-in intermediateCA.csr -out intermediateCA.crt \
-days 825 -create_serial -extensions intermediate_ca
  • View contents of crt
openssl x509 -noout -text -in intermediateCA.crt

Ensure that CA:true is present in certificate

  • Verify againt rootCA
openssl verify -CAfile rootCA.crt intermediateCA.crt
  • You would need a certificate chain file if you want to verify the server certificate (which you will generate later). This step is not required and you can directly use intermediateCA.crt if rootCA.crt is a standard CA or rootCA.crt is installed in that machine.
cat intermediateCA.crt rootCA.crt > ca-chain.crt

Create a certificate for your server(s)

This procedure needs to be followed for each server/appliance that needs a trusted certificate from our CA

  • Generate key and certificate signing request (same command as you did for intermediateCA.. just change text)
openssl req -newkey rsa:2048 -passout pass:"test" \
-subj "/C=US/ST=CA/O=SubOrg, Inc./CN=yourserver.net" \
-addext "subjectAltName=DNS:yourserver.net,DNS:www.yourserver.net" \
-keyout yourserver.key -out yourserver.csr
  • View contents of csr
openssl req -text -noout -verify -in yourserver.csr
  • Sign csr using intermediateCA
openssl x509 -req -in yourserver.csr -passin pass:"test" \
-CA intermediateCA.crt -CAkey intermediateCA.key \
-CAcreateserial -out yourserver.crt -days 825

Another way to sign is via ca

openssl ca -batch -config openssl.cnf \
-keyfile rootCA.key -cert rootCA.crt \
-in rmq.csr -out rmq.crt \
-days 825 -create_serial -extensions <name-of-extension-in-openssl.conf>

if you want to test expiry of your certificate use -startdate/enddate in YYMMDDHHMMSSZ format instead of -days

  • View contents of crt
openssl x509 -noout -text -in yourserver.crt
  • Verify againt intermediateCA
openssl verify -CAfile intermediateCA.crt yourserver.crt

If above fails, use the ca chain

openssl verify -CAfile ca-chain.crt yourserver.crt

Import the certificate to Java Keystore

  • Create a pkcs12 store with rootCA
keytool -importcert -trustcacerts \
-keystore common-truststore.p12 -storetype pkcs12 \
-alias rootCA -file rootCA.crt \
-storepass test -noprompt

Import keypair into Java Keystore

keytool does not offer such capabilities. Work around is to use openssl to combine cert and key into a p12 and then keytool import that into a keystore

cat yourserver.crt rootCA.crt > yourserver-chain.crt

openssl pkcs12 -export \
-in yourserver-chain.crt -inkey yourserver.key \
-name yourserver -out yourserver-temp.p12

//-password pass:YourPassword to automate

keytool -importkeystore \
-srckeystore yourserver-temp.p12 \
-destkeystore yourserver.p12 \
-srcstoretype pkcs12 \
-deststoretype pkcs12 \
-alias yourserver

  • Windows bash users can prefix winpty before openssl to enter tty mode

Generate PFX from key pair

openssl pkcs12 -export -out yourserver.pfx -inkey yourserver.key -in yourserver.crt

or if you want to include intermediate and rootCA use the following

openssl pkcs12 -export -out yourserver.pfx -inkey yourserver.key -in yourserver.crt -in intermediateCA.crt -in rootCA.crt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment