OpenSSL CA
Notes on creating your own Certificate Authority (CA) using openssl and managing client certificates signed by your CA.
Generate CA
Configuration
The following configuration files are needed before you can generate your CA certificate and issue/manage client certificates.
openssl-ca.cnf
Create a file called openssl-ca.cnf and add in the following:
HOME = . RANDFILE = $ENV::HOME/.rnd #################################################################### [ ca ] default_ca = CA_default # The default ca section [ CA_default ] default_days = 1000 # How long to certify for default_crl_days = 30 # How long before next CRL default_md = sha256 # Use public key default MD preserve = no # Keep passed DN ordering x509_extensions = ca_extensions # The extensions to add to the cert email_in_dn = no # Don't concat the email in the DN copy_extensions = copy # Required to copy SANs from CSR to cert base_dir = . certificate = $base_dir/cacert.pem # The CA certifcate private_key = $base_dir/cakey.pem # The CA private key new_certs_dir = $base_dir # Location for new certs after signing database = $base_dir/index.txt # Database index file serial = $base_dir/serial.txt # The current serial number unique_subject = no # Set to 'no' to allow creation of # several certificates with same subject. #################################################################### [ req ] default_bits = 4096 default_keyfile = cakey.pem distinguished_name = ca_distinguished_name x509_extensions = ca_extensions string_mask = utf8only #################################################################### [ ca_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = US stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Maryland localityName = Locality Name (eg, city) localityName_default = Baltimore organizationName = Organization Name (eg, company) organizationName_default = Test CA, Limited organizationalUnitName = Organizational Unit (eg, division) organizationalUnitName_default = Server Research Department commonName = Common Name (e.g. server FQDN or YOUR name) commonName_default = Test CA emailAddress = Email Address emailAddress_default = test@example.com #################################################################### [ ca_extensions ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always, issuer basicConstraints = critical, CA:true keyUsage = keyCertSign, cRLSign #################################################################### [ signing_policy ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional #################################################################### [ signing_req ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment
openssl-server.cnf
Create a file called openssl-server.cnf and add in the following:
HOME = . RANDFILE = $ENV::HOME/.rnd #################################################################### [ req ] default_bits = 2048 default_keyfile = serverkey.pem distinguished_name = server_distinguished_name req_extensions = server_req_extensions string_mask = utf8only #################################################################### [ server_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = US stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = MD localityName = Locality Name (eg, city) localityName_default = Baltimore organizationName = Organization Name (eg, company) organizationName_default = Test Server, Limited commonName = Common Name (e.g. server FQDN or YOUR name) commonName_default = Test Server emailAddress = Email Address emailAddress_default = test@example.com #################################################################### [ server_req_extensions ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment
#uncomment and update the [ alternate_names ] section below to add SANs to the cert #subjectAltName = @alternate_names
#uncomment if you wish to include a comment about the certificate #nsComment = "OpenSSL Generated Certificate" #################################################################### [ alternate_names ] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = mail.example.com DNS.4 = ftp.example.com
Create files
Two additional files are needed to issue certificates:
touch index.txt echo '01' > serial.txt
You also need to adjust the permission on these files in order for openssl to write to them:
chmod a+w index.txt chmod a+w serial.txt
Generate certificate
openssl req -x509 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM -days 3560
Note: 3560 is 10 years. You can also use -startdate and -enddate right after the -config option to specify a start and ending date for the validity of the CA certificate. Using this, the format is YYYYMMDDHHMMSSZ.
Verify certificate:
openssl x509 -in cacert.pem -text -noout openssl x509 -purpose -in cacert.pem -inform PEM
Generate Client
Create Certificate Signing Request
Create a Certificate Signing Request (CSR) to submit to your new CA:
openssl req -config openssl-server.cnf -newkey rsa:2048 -sha256 -nodes -out servercert.csr -outform PEM
Verify the CSR:
openssl req -text -noout -verify -in servercert.csr
Sign and issue cert
The following will sign the CSR with your CA's certificate, issuing a certificate:
openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles servercert.csr
Note: You can also use -startdate and -enddate right after the -config option to specify a start and ending date for the validity of the CA certificate. Using this, the format is YYYYMMDDHHMMSSZ.
Verify certificate issued:
openssl x509 -in servercert.pem -text -noout
The certificate will also be available in a .pem file that corresponds to the serial number it was issued under.