15 Jan 2007
The following openssl command generates a 2048-bit RSA key file:
openssl genpkey -out key.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048
The previous genrsa command has been deprecated:
openssl genrsa -out key.pem 2048
The key file will not have an associated password, allowing it to be used by a server.
The following openssl command generates a self-signed certificate file, cert.pem, using the key.pem above:
openssl req -new -x509 -key key.pem -out cert.pem -days 365
The resulting certificate file will be good for one year.
Use the hostname of the server (mail.example.com, for example) as the CN (Common Name) for the certificate.
To view the contents of cert.pem file, use the openssl command:
openssl x509 -in cert.pem -noout -text
The important information is the subject, particularly the CN (Common Name). Also, there may be Subject Alternate Names.
Certificate Request Generation
To create a certificate signing request:
openssl req -new -out request.csr -key key.pem
These CSR's can be sent to a certificate authority to be signed, resulting in a certificate.
The keytool command that comes with the JDK is capable of doing most of the common things that openssl does. One bit that is harder than it should be is importing an openssl-generated key and certificate into a keystore. The following two-step process can be used:
openssl pkcs12 -export -in cert.pem -inkey key.pem > server.pkcs12 > Enter Export Password: > Verifying - Enter Export Password: keytool -importkeystore -srckeystore server.pkcs12 -destkeystore server.keystore -srcstoretype pkcs12 > Enter destination keystore password: > Re-enter new password: > Enter source keystore password:
The export password given to openssl when creating the pkcs12 file should match the source keystore password given to keytool. This password apparently must be non-empty.
It is possible to arrange for a certificate to apply to more than one host (or Common Name) by using a certificate extension. Doing so requires
- modifying the openssl configuration file, and
- supplying the extra name information.
OpenSSL configuration file
I needed two modifications for the OpenSSL configuration file, /etc/ssl/openssl.cnf on my Ubuntu laptop. (You could modify a copy of the file and specify that on the command line, but I was lazy.)
First, enable the extensions:
[req] req_extensions = v3_req
(In the req section, this line should already exist, but be commented out.)
Second, add an entry in the v3_req section to collect the alternative names. One way is to read from an environment variable:
[ v3_req ] subjectAltName=$ENV::ALTNAME
This requires the ALTNAME environment variable to be set to something meaningful every time the command is used, so it may just be easier to set the values in the file. The syntax for doing so is:
Preferrably, for me, a new section could be used:
subjectAltName=@alt_names [alt_names] DNS.1 = <host1> DNS.2 = <host2>
Generating the certificate or signing request
To generate a signing request using the configuration file, use:
openssl req -new -out request.csr -key pem.key \ -config openssl.cnf
To generate a self-signed certificate using the configuration file (with the alternate names set in the file), use:
openssl req -new -x509 -key key.pem -out cert.pem -days 365 \ -config openssl.cnf
To generate the self-signed certificate using the environment variable, use the (much more complex) command:
ALTNAME="DNS:<host1>,DNS:<host2>" \ openssl req -new -x509 -key key.pem -out cert.pem -days 365 \ -config /etc/ssl/openssl.cnf -extensions v3_req
The ALTNAME environment variable supplies the additional host names to be used in the SubjectAltName extension to the certificate. The additional -config and -extensions arguments are needed to get openssl req to read and used the extension configurations.
Theoretically, the canonical name (the hostname used for the CN of the certificate) should not be needed in the list of alternative names. However, when I tried omitting the canonical name from the alternative name list, Firefox did not allow the certificate to be used with the canonical name because it did not belong, as if the subjectAltNames extension was overriding the CN. According to all the information I have seen, it hurts nothing to add the CN to the subjectAltNames list, and may be necessary depending on whether I was or was not doing something wrong.
Information on generating certificates with alternative names: