Use of Weak and Self-Signed SSL Certificates
How to Create Trusted Self-Signed SSL Certificates and Local Domains for est
Set up local test domains and enable a trusted, self-signed certificate for fast, local testing
Most of the time, we have domains other than localhost to test applications locally, and we also need trusted self-signed SSL certificates.
Self-Signed Certificate
A self-signed certificate is a certificate that is signed by the person who created it, rather than by a trusted certification authority. Development servers can be enabled with self-signed certificates to help us reduce the cost of certificates and also management overheads.
By default, the self-signed certificate throws a certificate validation error when accessing websites in browsers, but allows us to move to the real pages by accepting the risk. In some cases, self-signed certificates don't help us test some browser functionality that only works with valid SSL, such as testing APIs of different browsers, such as geolocation.
Now let's see how to quickly set up local domains and a trusted self-signed certificate for testing in Windows. the same can be used on other systems with some additional steps.
Local Domains
Sometimes we may need to have different domains to test our application in the development environment. DNS setup consumes more time and cost; native domains help us quickly test applications in development environments.
I'll define the following test domains — , , and . myexample.com
sub.myexample.com myexample1.com
Edit the Windows file, click the . Add the following entries to map test domains so that the defined domains can access the application running on localhost within the same machine. hosts
C:WindowsSystem32driversetchosts
127.0.0.1
127.0.0.1 myexample.com
127.0.0.1 sub.myexample.com
127.0.0.1 myexample1.com
Now let's create a self-signed certificate via OpenSSL.
Creating a Root SSL Certificate
Create an RSA-2048 key and save it to the file. rootCA
.key
openssl genrsa -des3 -out rootCA.key 2048
When you get "Enter password for rootCA.key", enter a password and store it securely.
Create a root certificate through the generated key.
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1460 -out rootCA.pem
Change the validity days as needed.
When you get "Enter passphrase for rootCA.key", enter the password that was used to create the root key.
Enter any other optional information:
- Country Name (2-letter code) [AU]: USA
- State or Province Name (full name) [Some States]: MN
- Place Name (for example, city) []: Eagan
- Organization Name (e.g., company) [Internet Widgits Pty Ltd]: Technology Forum
- Organizational Unit Name (e.g. section) []: Marketing
- Common Name (for example, server FQDN or YOUR name) []: Local certificate
- Email Address []:
[email protected]
Trust the Root SSL Certificate:
Now the root certificate is ready. Let's trust the root SSL certificate on the local system.
Run the following command from a command prompt (run with elevated access):
certutil -addstore -f "ROOT" rootCA.pem
The root certificate is now added as part of Trusted Root Certification Authorities.
You can verify the certificate through Certificate Manager or the . Certmgr.msc
Even the root certificate can be managed through browsers: in Chrome, go to Privacy and Security → Settings → Security → Manage Certificates → Trusted Root Certification Authorities.
You can import/export and remove the certificate (certificates cannot be removed if imported as follows):Certmgr.msc
If you use Firefox for local testing, it will ignore root certificates in the Windows certificate store (Chrome and Edge refer to root certificates in the Windows certificate store). The self-signed root certificate must be imported into Firefox separately.
Options→ Go to Privacy and Security → Security → Certificates → view the certificates.
You can import/export and remove certificates. Import the Root CA certificate created in the previous steps. Select "Trust this CA to define websites."
Create an SSL SAN Certificate with a Root Certificate
The root certificate is now trusted. Let's give you an SSL certificate to support our local domains – , , and for testing. myexample.com
sub.myexample.com
myexample1.com
localhost
Create a new OpenSSL configuration file so that the configuration details are available when the certificate is created. server.csr.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[dn]
C=US
ST=MN
L=Eagan
O=Tech Forum
OU=Marketing
[email protected]
CN = localhost
Create a file with a list of local SAN domains:v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names[alt_names]
DNS.1 = myexample.com
DNS.2=sub.myexample.com DNS.3=myexample1.com
DNS.4=localhost
Create a private key and certificate-signing request (CSR) for the localhost certificate.
openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config server.csr.cnf
This private key is stored on . server.key
Let's issue a certificate via the root SSL certificate and the CSR created earlier.
openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 500 -sha256 -extfile v3.ext
When it says "Enter passphrase for rootCA.key," enter the passphrase used while generating the root key.
The output certificate is stored in a file called . server.crt
Enable the SSL Certificate for the Local Server
Let's now enable the certificate for the local server. I'm going to configure the certificate with the Express.js application to enable the trusted SSL communication.
app.js
var express = require('express')const path = require('path')
const https = require('https');
const fs = require('fs');var app = express ()app.get('/index.html', function (req, res) {res.sendFile('index.html', { root: path.join(__dirname, '.') })})https.createServer({ key: fs.readFileSync('ssl\server.key'), cert: fs.readFileSync('ssl\server.crt')}, app).listen(443, function()
{
console.log('Example app listening on port 443!
Go to https://localhost/')})
Now the certificate is trusted from the browser for the test domains , , , and . myexample.com
sub.myexample.com
myexample1.com
localhost
The trusted, self-signed certificate can be used for development and initial testing with local domains. This will help us quickly enable trusted local domains to test some scenarios that require a trusted SSL certificate.