If you need to locally test your websites with HTTPS, purchasing an SSL certificate for this purpose might not be ideal. Instead, creating your own certificates is the way to go!
Navigating through the OpenSSL command-line interface can be daunting. With its myriad of options, it’s easy to get lost.
For a quick and easy solution, **Check out the bash scripts in the repo, dev-certificates
, to create development certificates the easy way.
If you want to step through the creation of a Self-Signed Wildcard SSL Certificate for internal use, development, and testing, check out the guide below
Install OpenSSL
Where is OpenSSL?
which openssl
/usr/bin/openssl
If the which
command does not return a path then you will need to install openssl yourself:
- Mac OS: Use Homebrew:
brew install openssl
- Windows: Windows complete package .exe installer
- Debian/Ubuntu Linux:
apt-get install openssl
- Centos/RHEL:
yum install openssl
Step 1 : Create the CA Private Key
After installing OpenSSL, the subsequent action involves creating a private key. This key is critical in SSL certificates to sign and decrypt information.
To generate a 2048-bit RSA private key, execute the command provided below. Replace private.key
with your desired file name.
export KEYSIZE=2048
# openssl genrsa -des3 -out CAPrivate.key $KEYSIZE
openssl genrsa -out CAPrivate.key $KEYSIZE
Notes:
- When choosing the key size, opt for a minimum bit length of 2048 for RSA and 256 for ECDSA, as these are the minimum accepted sizes for SSL certificates.
- Using
-des3
for encrypting the key with Triple DES is a matter of security policy and preference rather than a strict requirement. It requires a passphrase to be entered every time the key is accessed, which can protect it if it falls into the wrong hands. - Ensure the security of your private key, as it is vital for upholding the integrity of your SSL certificate.
Step 2: Generate the CA Root certificate
Next, we create a self-signed (“X.509
”) certificate. The certificate is generated using the private key CAPrivate.key
and is not encrypted with a passphrase.
export VALIDITY=365
openssl req -x509 -new -nodes \
-key CAPrivate.key \
-sha256 \
-days $VALIDITY \
-out CAPrivate.pem
Explanation:
-new
: Indicates that this is a new request.-nodes
: Stands for “no DES,” meaning the private key should not be encrypted with a passphrase. This is useful when the key must be used automatically and without manual intervention to enter a passphrase.-key CAPrivate.key
: This specifies the private key to use when creating the certificate. Here, it’s using theCAPrivate.key
, presumably the private key of your Certificate Authority (CA).-sha256
: This tells OpenSSL to use the SHA-256 hashing algorithm. SHA-256 is a cryptographic hash function considered secure and commonly used for certificate signatures.-days $VALIDITY
: This sets the number of days for the certificate to be valid.$VALIDITY
should be replaced with the desired number of days. For example, to make the certificate valid for one year, you would replace$VALIDITY
with365
.-out CAPrivate.pem
: Specifies the output file for the certificate. The certificate will be saved asCAPrivate.pem
.
Step 3: Create a Private Key
export KEYSIZE=2048
openssl genrsa -out private.key $KEYSIZE
Step 4: Create a Certificate Signing Request (CSR)
Now generate a new Certificate Signing Request (CSR) using our previously created private key. The CSR will include specific extensions defined for a CA certificate (v3_ca
). This CSR can then be submitted to a Certificate Authority for signing to obtain a certificate based on the public key in the CSR and the information it contains.
openssl req -new -key private.key -extensions v3_ca -out request.csr
Explanation:
-new
: This flag indicates that you are creating a new CSR.-key private.key
: This specifies the private key that will be used to sign the CSR. In this case, it’s usingprivate.key
. This key is essential for the CSR as it pairs the request with the key used for the corresponding certificate.-extensions v3_ca
: This option is used to specify the extensions to be added to the CSR.v3_ca
refers to a section in the OpenSSL configuration file defining the extensions for a CA (Certificate Authority) certificate. This is important for defining the capabilities and roles of the certificate.-out request.csr
: This specifies the output filename for the CSR. The CSR will be saved asrequest.csr
.
Step 5: Create an extensions file to specify subjectAltName
Create an extensions file named: openssl.ss.cnf
. In this file replace *.armand.nz
with your domain:
export BASICCONSTRAINTS="CA:FALSE"
export SUBJECTALTNAME="DNS:*.armand.nz"
export EXTENDEDKEYUSAGE="serverAuth"
cat >> openssl.ss.cnf << EOL
basicConstraints=$BASICCONSTRAINTS
subjectAltName=$SUBJECTALTNAME
extendedKeyUsage=$EXTENDEDKEYUSAGE
EOL
A more verbose template you can base your config on looks like:
[req]
default_md = sha256
prompt = no
req_extensions = req_ext
distinguished_name = req_distinguished_name
[req_distinguished_name]
commonName = *.armand.nz
countryName = US
stateOrProvinceName = No state
localityName = City
organizationName = LTD
[req_ext]
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=critical,serverAuth,clientAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=yourdomain.com
DNS.2=*.yourdomain.com
Step 6: Generate the Certificate using the CSR
Lastly, we will use OpenSSL to sign a CSR with a CA’s certificate and private key, generating a new SSL/TLS certificate valid for the specified number of days and using SHA-256 as the hashing algorithm.
export VALIDITY=365
openssl x509 -req -in request.csr \
-CA CAPrivate.pem \
-CAkey private.key \
-CAcreateserial \
-extfile openssl.ss.cnf \
-days $VALIDITY \
-sha256 \
-out MyCert.crt
Explanation:
-req
: This option indicates that the input is a CSR.-in request.csr
: Specifies the input file, which is the CSR (request.csr
) that you want to sign to create the certificate.-CA CAPrivate.pem
: This specifies the CA (Certificate Authority) certificate to be used for signing the CSR.CAPrivate.pem
is expected to be the public certificate of the CA.-CAkey private.key
: Refers to the private key of the CA (private.key
) that corresponds to the public certificate specified in-CA
.-CAcreateserial
: Instructs OpenSSL to create a serial number for the certificate if one doesn’t already exist. This is important for uniquely identifying certificates issued by the CA.-extfile openssl.ss.cnf
: Specifies an external configuration file (openssl.ss.cnf
) that contains additional configuration options, possibly including extensions to be added to the certificate.-days $VALIDITY
: Sets the validity period of the certificate to the number of days specified by theVALIDITY
environment variable, which was set earlier to 365 days.-sha256
: Indicates that the SHA-256 hashing algorithm should be used for signing the certificate, which is a secure and widely-used hashing algorithm.-out MyCert.crt
: Specifies the output file for the signed certificate. The resulting certificate will be saved asMyCert.crt
.
Step 7: Install the Certificate and Private Key on your Server or Application
Refer to the Server or Application’s documentation to learn how to do this step
Step 8: Copy the CA Root certificate and import it into the proper Certificate Store of the OS/Application or client device
This step is optional (for in which case you will see “insecure” warnings) or, in some cases, might be required. Refer to the Server or Application’s documentation to learn how to do this step and take note of whether a specific naming convention or file type is required.
For Example: