I can`t comment so I add a separate answer.
I tried to create a self-signed certificate for NGINX and it was easy, but when I wanted to add it to Chrome white list I had a problem. And my solution was to create a Root certificate and signed a child certificate by it.
So step by step.
Create file config_ssl_ca.cnf
Notice, config file has an option basicConstraints=CA:true which means that this certificate is supposed to be root.
This is a good practice, because you create it once and can reuse.
[ req ]
default_bits = 2048
prompt = no
distinguished_name=req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
countryName=UA
stateOrProvinceName=root region
localityName=root city
organizationName=Market(localhost)
organizationalUnitName=roote department
commonName=market.localhost
emailAddress=root_email@root.localhost
[ alternate_names ]
DNS.1 = market.localhost
DNS.2 = www.market.localhost
DNS.3 = mail.market.localhost
DNS.4 = ftp.market.localhost
DNS.5 = *.market.localhost
[ v3_req ]
keyUsage=digitalSignature
basicConstraints=CA:true
subjectKeyIdentifier = hash
subjectAltName = @alternate_names
Next config file for your child certificate will be call config_ssl.cnf.
[ req ]
default_bits = 2048
prompt = no
distinguished_name=req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
countryName=UA
stateOrProvinceName=Kyiv region
localityName=Kyiv
organizationName=market place
organizationalUnitName=market place department
commonName=market.localhost
emailAddress=email@market.localhost
[ alternate_names ]
DNS.1 = market.localhost
DNS.2 = www.market.localhost
DNS.3 = mail.market.localhost
DNS.4 = ftp.market.localhost
DNS.5 = *.market.localhost
[ v3_req ]
keyUsage=digitalSignature
basicConstraints=CA:false
subjectAltName = @alternate_names
subjectKeyIdentifier = hash
The first step - create Root key and certificate
openssl genrsa -out ca.key 2048
openssl req -new -x509 -key ca.key -out ca.crt -days 365 -config config_ssl_ca.cnf
The second step creates child key and file CSR - Certificate Signing Request. Because the idea is to sign the child certificate by root and get a correct certificate
openssl genrsa -out market.key 2048
openssl req -new -sha256 -key market.key -config config_ssl.cnf -out market.csr
Open Linux terminal and do this command
echo 00 > ca.srl
touch index.txt
The ca.srl text file containing the next serial number to use in hex.
Mandatory. This file must be present and contain a valid serial number.
Last Step, crate one more config file and call it config_ca.cnf
# we use 'ca' as the default section because we're usign the ca command
[ ca ]
default_ca = my_ca
[ my_ca ]
# a text file containing the next serial number to use in hex. Mandatory.
# This file must be present and contain a valid serial number.
serial = ./ca.srl
# the text database file to use. Mandatory. This file must be present though
# initially it will be empty.
database = ./index.txt
# specifies the directory where new certificates will be placed. Mandatory.
new_certs_dir = ./
# the file containing the CA certificate. Mandatory
certificate = ./ca.crt
# the file contaning the CA private key. Mandatory
private_key = ./ca.key
# the message digest algorithm. Remember to not use MD5
default_md = sha256
# for how many days will the signed certificate be valid
default_days = 365
# a section with a set of variables corresponding to DN fields
policy = my_policy
# MOST IMPORTANT PART OF THIS CONFIG
copy_extensions = copy
[ my_policy ]
# if the value is "match" then the field value must match the same field in the
# CA certificate. If the value is "supplied" then it must be present.
# Optional means it may be present. Any fields not mentioned are silently
# deleted.
countryName = match
stateOrProvinceName = supplied
organizationName = supplied
commonName = market.localhost
organizationalUnitName = optional
commonName = supplied
You may ask, why so difficult, why we must create one more config to sign child certificate by root. The answer is simple because child certificate must have a SAN block - Subject Alternative Names.
If we sign the child certificate by "openssl x509" utils, the Root certificate will delete the SAN field in child certificate.
So we use "openssl ca" instead of "openssl x509" to avoid the deleting of the SAN field. We create a new config file and tell it to copy all extended fields copy_extensions = copy.
openssl ca -config config_ca.cnf -out market.crt -in market.csr
The program asks you 2 questions:
- Sign the certificate? Say "Y"
- 1 out of 1 certificate requests certified, commit? Say "Y"
In terminal you can see a sentence with the word "Database", it means file index.txt which you create by the command "touch". It will contain all information by all certificates you create by "openssl ca" util.
To check the certificate valid use:
openssl rsa -in market.key -check
If you want to see what inside in CRT:
openssl x509 -in market.crt -text -noout
If you want to see what inside in CSR:
openssl req -in market.csr -noout -text