Creating a Self-Signed Root CA Certificate with OpenSSL
The following example shows how to use OpenSSL to:
- create a Self-Signed Root Certificate for a Root Certificate Authority (CA)
- Use the root certificate to create a certificate for an intermediate CA
- issue a server certificate.
The OpenSSL commands and configurations are examples to demonstrate the possibility of using OpenSSL in combination with a Securosys HSM for PKI applications. Some of the tools are not considered to have "production quality" by OpenSSL itself:
This command was originally meant as an example of how to do things in a CA. Its code does not have production quality. It was not supposed to be used as a full blown CA itself -- openssl-ca man page
Preparation
-
Create the directories and initial files
mkdir -p myCA/{rootCA,intermediateCA}/{certs,crl,newcerts,private,csr}
touch myCA/rootCA/index.txt
echo 1000 > myCA/rootCA/serial
echo 1000 > myCA/rootCA/crlnumber
touch myCA/intermediateCA/index.txt
echo 1000 > myCA/intermediateCA/serial
echo 1000 > myCA/intermediateCA/crlnumber -
Download the configuration for the root CA openssl_root.cnf, and the intermediate CA openssl_intermediate.cnf. These two configurations specify constraints, policies and extensions that are applied to the certificates they create and sign.
Root CA certificate
-
Create a key.
openssl genpkey -propquery "provider=pkcs11" \
-algorithm rsa -pkeyopt rsa_keygen_bits:4096 \
-pkeyopt pkcs11_uri:"pkcs11:object=MyRootCA"noteIf your pkcs11-provider is configured to access to multiple partitions on the HSM the pkcs11-uris used in these examples are ambiguous. Additionally specify the partition by adding the
token
attribute to the URI. E.g.: Usepkcs11:object=MyRootCA;token=<USER_PARTITION_NAME>
instead ofpkcs11:object=MyRootCA
. -
Create a self-signed certificate. The v3_ca extensions defined in the openssl_root.cnf configuration are applied which enable the "CA:true" property.
openssl req -config openssl_root.cnf \
-key "pkcs11:object=MyRootCA" \
-new -x509 -days 7300 -sha256 -extensions v3_ca \
-out myCA/rootCA/certs/ca.cert.pem \
-subj "/C=CH/ST=Zurich/L=Zurich/O=My Example Organisation/OU=IT Department/CN=Root CA"
Intermediate CA certificate
-
Create a key.
openssl genpkey -propquery "provider=pkcs11" \
-algorithm rsa -pkeyopt rsa_keygen_bits:4096 \
-pkeyopt pkcs11_uri:"pkcs11:object=MyIntermediateCA" -
Create a certificate signing request (CSR).
openssl req -config openssl_intermediate.cnf \
-key "pkcs11:object=MyIntermediateCA" \
-new -sha256 \
-out myCA/intermediateCA/certs/intermediate.csr.pem \
-subj "/C=CH/ST=Zurich/L=Zurich/O=My Example Organisation/OU=IT Department/CN=Intermediate CA" -
As root CA, sign the CSR for the intermediate CA with the root CA key.The v3_intermediate_ca extensions defined in the openssl_root.cnf configuration are applied.
openssl ca -batch -config openssl_root.cnf \
-keyfile "pkcs11:object=MyRootCA" \
-extensions v3_intermediate_ca -days 750 -notext -md sha256 \
-in myCA/intermediateCA/certs/intermediate.csr.pem \
-out myCA/intermediateCA/certs/intermediate.cert.pem -
Verify the signature on the intermediate certificate
openssl verify -CAfile myCA/rootCA/certs/ca.cert.pem \
myCA/intermediateCA/certs/intermediate.cert.pem
Server certificate
-
Create a key.
openssl genpkey -propquery "provider=pkcs11" \
-algorithm rsa -pkeyopt rsa_keygen_bits:4096 \
-pkeyopt pkcs11_uri:"pkcs11:object=server-www.example.com" -
Create a certificate signing request (CSR).
openssl req -copy_extensions=copyall \
-key "pkcs11:object=server-www.example.com" \
-new -sha256 \
-out server-www.example.com.csr.pem \
-subj "/C=CH/ST=Bern/L=Bern/O=My Example Organisation/OU=IT Department/CN=www.example.com" \
-addext "subjectAltName = DNS:www.example.com, DNS:*.www.example.com" -
As intermediate CA, sign the server CSR with the intermediate CA key.
openssl ca -batch -config openssl_intermediate.cnf \
-extensions v3_server_cert \
-keyfile "pkcs11:object=MyIntermediateCA" \
-days 40 -notext -md sha256 \
-in server-www.example.com.csr.pem \
-out server-www.example.com.cert.pem -
Verify the certificate by checking the signatures using OpenSSL.
cat myCA/intermediateCA/certs/intermediate.cert.pem \
myCA/rootCA/certs/ca.cert.pem \
> chain.pem
openssl verify -show_chain \
-trusted myCA/rootCA/certs/ca.cert.pem \
--untrusted chain.pem \
server-www.example.com.cert.pemAdditionally test the certificate by starting a https server
openssl s_server \
-cert server-www.example.com.cert.pem \
-key 'pkcs11:object=server-www.example.com' \
-chainCAfile chain.pem -naccept +1and connecting to it
curl -v --cacert myCA/rootCA/certs/ca.cert.pem \
--connect-to www.example.com:443:localhost:4433 \
https://www.example.com