Here's a brief summary of how to generate a self signed certificate for localhost. Basically, there are 3 steps.
Generate CA keys
# generate CA private key
openssl genrsa -out CA.key -des3 2048
# generate CA public key with private key
openssl req -x509 -sha256 -new -nodes -days 3650 -key CA.key -out CA.pem
Generate server keys for signing
# generate server private key
openssl genrsa -out localhost.key -des3 2048
# generate a signing request
openssl req -new -key localhost.key -out localhost.csr
# A certificate extensions file is needed to store server name related info
echo 'authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1' > localhost.ext
# A decrypted form of your private key is alos needed to load it in server
openssl rsa -in localhost.key -out localhost.decrypted.key
Sign server key with CA key
# sign signing request with CA private key for 397 days
openssl x509 -req -in localhost.csr -CA CA.pem -CAkey CA.key -CAcreateserial -days 397 -sha256 -extfile localhost.ext -out localhost.crt
# convert crt to pem public key
openssl x509 -in localhost.crt -out localhost.pem -outform PEM
# concat localhost pem with CA pem, this is your server public key
cat CA.pem >> localhost.pem
Why 397 days?
The server licensed to 397 days to avoid chrome with this error: ERR_CERT_VALIDITY_TOO_LONG.
To avoid the risk of misissuance, such as due to leap seconds or CA-configured randomization, CAs SHOULD issue such server certificates with validity periods of 397 days or less.