Managing public key infrastructure
Generate keys
Generate 2048 bit RSA key using openssl:
openssl genrsa -out private.key 2048
Key with higher bit size (say, RSA 4096 bit or even 8192 bit) are more secure but it comes with additional computing overhead for encryption and decryption.
The key generated in the above command contains both private and the public keys. Extract the public key:
openssl rsa -pubout -in private.key
We can encrypt the private.key
with a passphrase during creation instead of
writing in plaintext:
openssl genrsa -aes256 -out private.key 2048
Convert an encrypted key file to a un-encrypted file:
openssl rsa -in private.key -out unencrypted.key
Inspect various details in a private key:
openssl rsa -text -in private.key
openssl rsa -check -noout -in private.key
Certificate Signing Request
Create CSR (interactively, it will ask for various required and optional parameters):
openssl req -new -key private.key -out domain.example.com.csr
Create CSR non-interactively:
openssl req -new -key private.key -noenc \
-subj '/CN=example.com/O=Example Inc./OU=Engineering/C=US/ST=California/L=San Francisco/emailAddress=email@example.com' \
-addext "keyUsage = digitalSignature,keyAgreement" \
-addext "extendedKeyUsage = serverAuth, clientAuth" \
-out example.com.csr
Create private key and csr together:
openssl req -new -noenc \
-subj '/CN=domain.example.com/O=Example Ltd/C=SG/L=Singapore' \
-newkey rsa:2048 -keyout private2.key -out domain2.example.com.csr
Check CSR details:
openssl req -text -noout -verify -in mongo.csr.pem
Self-sign certificates
Self-signed certificates are intended for testing and development purposes only. Generate a self-signed certificate for root of trust:
openssl req -x509 -days 365 -noenc \
-subj '/CN=ROOT/O=ROOT/C=SG/L=Singapore' -key private.key -out ca.crt
Use the self-signed root signing certificate to generate a signed certificate from the certificate request:
openssl x509 -req -in domain.example.com.csr -days 365 -CA ca.crt \
-CAkey private.key -CAcreateserial -out domain.example.com.crt
Do all the above in a single step:
openssl req -new -x509 -days 365 -noenc -newkey rsa:2048 -keyout private.key \
-out public.crt -subj '/CN=domain.example.com/O=Example Ltd/C=SG/L=Singapore'
Use CA to sign
For production usage, we should be using a third-party CA authority. In case of a own CA implementation, we could use a separate root or intermediatory CA key and certificate to sign. Better care should be taken when creating a root certificate, e.g., a larger size key and encrypt the key file.
openssl genrsa -out ca.key -aes256 8192
Generate CA public certificate:
openssl req -x509 -new -extensions v3_ca -key ca.key -days 365 -out ca.crt \
-subj '/CN=ca.example.com/O=CA Inc./C=SG/L=Singapore'
Sign CSR:
openssl x509 -req -in domain.example.com.csr -CA ca.crt -CAkey ca.key \
-days 365 -out domain.example.com.crt
Check certificate details:
openssl x509 -text -noout -in domain.example.com.crt
Verify:
openssl verify -CAfile ca.crt domain.example.com.crt