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