OpenSSL Certificate Authority

From Sfvlug

To generate a private key, you don't need a config file. Just execute the following.

openssl genrsa -out example.key 1024

You may not wish to be prompted for a passphrase, because then you will have to enter the passphrase every time you use the resulting key (like restarting httpd). In this case, indlude the -nodes flag before the number of bits.

Set up the directory to hold the Certificate Authority. $CA_ROOT can be something like /opt/ca.

mkdir -m 0700 -p $CA_ROOT/{certs,crl,csr,private}
touch $CA_ROOT/index.txt
echo 01 > $CA_ROOT/serial

Here is a functional openssl.cnf for a Certificate Authority.

[ ca ]
default_ca		= rootca

[ rootca ]
dir			= /opt/ca
certificate		= $dir/private/ca.crt
private_key		= $dir/private/ca.key
database		= $dir/index.txt
serial			= $dir/serial
new_certs_dir		= $dir/certs

default_crl_days	= 7
default_days		= 365
default_md		= md5
crlDistributionPoints   = URI:http://sslcert.example.com/example.crl

policy			= rootca_policy
x509_extensions		= certificate_extensions

copy_extensions		= copy

[ rootca_policy ]
commonName		= supplied
organizationName	= supplied
organizationalUnitName	= optional
countryName		= supplied
stateOrProvinceName	= supplied
localityName		= supplied
emailAddress		= supplied

[ certificate_extensions ]
basicConstraints	= CA:false

[ req ]
default_bits		= 4096
default_keyfile		= /opt/ca/private/ca.key
default_md		= md5

prompt			= no
distinguished_name	= root_ca_distinguished_name
x509_extensions		= root_ca_extensions

[ root_ca_distinguished_name ]
commonName		= Example Corp., Inc.
organizationName	= Certificate Authority
countryName		= US
stateOrProvinceName	= California
localityName		= Los Angeles
emailAddress		= root@example.com

[ root_ca_extensions ]
basicConstraints	= CA:true

To generate the CA Certificate, you can either generate the private key at the same time or ahead of time using the instructions above. If the private key is already generated, use the following:

openssl req -x509 -config openssl.cnf -key ca.key -out ca.crt

Or to generate the key at the same time use:

openssl req -x509 -config openssl.cnf -newkey rsa:1024 -keyout ca.key -out ca.crt

And if you just want to generate a self-signed key for use on a web server or similar, make sure basicConstraints is set to CA:false. You can do this by the setting for X.509 extensions in the req section of the conf file. Either point x509_extensions at the certificate_extensions section where CA is false, or change basicConstraints under the root_ca_extensions to CA:false.

The above should be maintained on the host where the CA resides. It is best to make a new config file for every key pair you need to generate. Create the key on the host where the service it will be used with is running, in a directory related to the service. For example, make a new config file to generate a key and csr for a web server on that web server host, in a directory associated with the web server's configuration, such as /etc/httpd/ssl or similar. The logic behind this is that you want to minimize any risk associated with exposing the private key to the network. Therefore, generate the private key followed by the csr on the server where it will be used. Here is an openssl.cnf for creating a Request with Subject Alternative Names.

#oid_section			= new_oids
#
#[ new_oids ]
## RFC 3920 section 5.1.1 defines this OID
#xmppAddr   	   	 	= 1.3.6.1.5.5.7.8.5

[ req ]
default_bits			= 4096
default_keyfile			= san-example.key
distinguished_name		= distinguished_name
req_extensions			= v3_extensions
x509_extensions			= v3_extensions

# don't ask about the DN
prompt				= no

[ distinguished_name ]
countryName			= US
stateOrProvinceName		= California
localityName			= Los Angeles
organizationName		= Example Corp., Inc.
commonName			= example.com
emailAddress			= root@example.com

[ v3_extensions ]
# for certificate requests (req_extensions)
# and self-signed certificates (x509_extensions)
basicConstraints		= CA:FALSE
keyUsage			= digitalSignature,keyEncipherment
subjectAltName			= @subject_alternative_name

[ subject_alternative_name ]
email.0				= root@example.com
DNS.1				= www.example.com
URI.2				= URI:http://www.example.com/
IP.3				= 192.168.1.1
IP.4				= fe80::1

To generate the Certificate Signing Request, use the following command.

openssl req -nodes -config ./openssl.cnf -newkey rsa:4096 -keyout new.key -out new.csr

The above command generates the private key and the request at the same time. If you have already generated the key, replace -newkey with -key. If you want the private key to be password protected, drop the -nodes flag.

Once the request is generated, it can be signed by the CA. Use the following command to do so.

openssl ca -config /opt/ca/openssl.cnf -in new.csr

You can add -days NUM to change the default expiration of the generated certificate. This will dump the certificate to stdout, and save it as a file in the directory specified as new_cert_dir, named SERIAL.pem, where the next SERIAL is specified in the serial file. Basically, it will be the largest number in the directory. Send this back to the system that is making the request.

You should be aware that Keys are private and that Requests (unsigned) and Certificates (signed) are pubic, so it is ok to copy the *.csr and *.crt over the network in the clear, but never send the *.key out.

You can read the data in the request and the certificate, to make sure they were generated correctly or help you identify them. To read the request, use the following:

openssl req -text -in new.csr

And to read the certificate, the syntax is nearly identical:

openssl x509 -text -in new.crt

Jeff

Personal tools