Creating a Self-Signed Root CA Certificate with OpenSSL
Introduction
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.txtecho 1000 > myCA/rootCA/serialecho 1000 > myCA/rootCA/crlnumbertouch myCA/intermediateCA/index.txtecho 1000 > myCA/intermediateCA/serialecho 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
tokenattribute 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.pemopenssl 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