Skip to main content

Create a custom Certificate Authority (CA)

info
  • The Subject Alt Names are required in Google Chrome 58 and later, and is used to match the domain name and the certificate.
  • If the domain name is not listed in the certificate's Subject Alternative Names list, you'll get a NET::ERR_CERT_COMMON_NAME_INVALID error message.

1. Create a custom Certificate Authority (CA)

1.1. Generate the CA certificate key. Make sure to remember the passphrase.

# Generate the CA key
openssl genrsa -des3 -out ca.key 4096

1.2. Generate the CA certificate.

# Generate the CA certificate
openssl req -x509 -new -nodes -key ca.key -sha256 -days 10950 -out ca.pem -subj "/C=LK/ST=Western Province/L=Colombo/O=Example (Private) Limited/OU=Development/CN=Example Development Certificate Authority"

1.3. Verify certificate data.

# Verify certificate data
openssl x509 -in ca.pem -text -noout

You should get an output like below.

Certificate:
Data:
Version: 3 (0x2)
Serial Number:
fb:3d:42:e0:f0:a7:45:71
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=LK, ST=Western Province, L=Colombo, O=Example (Private) Limited, OU=Development, CN=Example Development Certificate Authority
Validity
Not Before: Dec 6 22:06:56 2020 GMT
Not After : Nov 29 22:06:56 2050 GMT
Subject: C=LK, ST=Western Province, L=Colombo, O=Example (Private) Limited, OU=Development, CN=Example Development Certificate Authority
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:a1:92:16:00:aa:d5:4d:6b:1a:cc:27:cb:b8:fa:
99:16:5e:ec:34:f9:11:f3:31:39:2d:6d:5e:fe:11:
98:7a:f3:ec:58:ab:71:cf:99:36:5c:03:9e:3f:33:
14:df:39:40:0c:3d:91:4f:04:7c:e1:3f:ff:53:53:
5a:f7:22:4f:87:0a:6a:29:9a:5c:ac:8a:fe:cb:4b:
bf:ec:41:d9:3a:59:53:31:70:3d:42:75:20:e8:58:
a0:ff:b3:60:3d:35:df:fd:fb:2b:82:c2:a1:66:05:
22:0e:96:21:6c:ea:53:5c:92:f5:66:4f:72:a0:79:
c4:7e:ae:10:4a:79:00:ae:6f:d4:3a:24:00:6c:11:
22:d6:e2:1c:c8:03:df:87:ae:c5:59:00:7c:c6:59:
1f:76:ce:4f:cb:66:3f:c9:74:be:6a:f0:ac:09:ef:
97:f3:0d:93:f7:bf:0f:50:a6:80:10:56:b4:aa:32:
81:7b:45:36:0b:1d:1c:75:36:82:89:fb:9f:c2:9e:
3d:40:bb:5d:8e:08:84:2f:9b:dc:79:1a:2f:bc:a9:
4c:31:e5:58:50:bc:f8:6d:fd:96:39:46:81:7f:f8:
99:19:81:25:f4:3c:2c:7b:6d:a2:2d:75:89:2b:54:
2a:9b:f1:8b:45:04:ac:76:24:6e:89:f0:fa:c5:c0:
fb:7d:0b:60:1e:d7:3d:e5:e3:7f:92:30:d5:9e:90:
06:ce:d8:7e:96:f2:24:72:bb:59:4a:5c:ce:f8:f7:
76:9e:98:b4:b1:f8:ee:fe:a3:0b:2d:47:2b:88:60:
68:1b:98:f1:59:13:f1:cc:b9:4e:36:0a:a5:0d:72:
f5:24:ce:ac:a3:41:8c:f6:48:f1:fb:c8:ae:07:b5:
51:7a:fe:5e:a4:86:b4:81:87:24:4b:81:44:2a:9c:
31:55:b7:20:58:ff:b4:92:d0:09:59:39:3c:fe:8a:
b8:75:37:b4:0c:b3:58:7e:9a:c5:8e:d9:10:37:3d:
7d:06:01:95:18:47:33:4c:e0:03:b6:4a:89:cb:85:
72:b2:d4:a9:a1:5a:f5:8a:83:7c:37:fe:ad:0e:22:
7d:ad:a0:e4:09:7e:ad:0b:86:17:fa:5b:af:de:98:
2e:10:76:0b:9d:5f:43:4d:b3:5f:55:03:95:84:59:
ec:c2:72:03:54:33:53:48:b9:da:29:98:a1:45:1f:
31:c4:3b:55:b2:c4:c2:94:72:77:c2:d3:92:9d:f4:
ea:ed:7a:9c:10:e6:fe:a0:55:48:84:d8:f9:b8:7d:
a8:42:c5:a2:e9:f3:d9:d2:9d:bc:bd:45:b3:e1:f8:
44:7a:5e:7b:57:81:67:f5:32:d4:f4:d4:f8:af:c6:
fd:09:b9
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
BA:D6:70:47:A0:9C:21:28:13:D2:08:13:6B:51:77:FD:5D:6F:67:D3
X509v3 Authority Key Identifier:
keyid:BA:D6:70:47:A0:9C:21:28:13:D2:08:13:6B:51:77:FD:5D:6F:67:D3

X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
3b:0c:db:9e:3c:72:2d:c1:7c:9c:97:2f:01:cb:8b:40:68:ff:
ac:6f:00:a5:17:44:b8:ad:de:1f:62:af:0a:e4:ea:05:2d:11:
5d:58:1f:70:24:6e:db:7b:44:7e:6c:9c:f5:8f:09:26:13:0d:
7b:55:a8:e8:b7:db:22:41:85:94:ec:4d:40:04:74:51:a1:0d:
6d:59:3e:a3:ab:01:2b:7b:f6:8f:31:93:fb:e4:07:f0:a5:3c:
4f:e8:5b:65:29:8e:e4:20:ac:d7:d7:1a:78:eb:68:bb:cb:3e:
b4:3a:34:6c:2b:0e:c0:bd:c1:a8:e7:d0:72:68:e9:60:58:8c:
33:a7:4c:55:bb:c1:02:b7:05:70:96:81:5f:29:02:a5:a2:cb:
ff:ca:39:02:bc:4d:52:e8:3f:6e:5b:e3:0a:d8:b1:65:ef:13:
81:eb:12:3b:8b:2e:0c:a8:e4:8a:db:3c:50:eb:5f:71:25:17:
6f:b6:d2:64:12:09:3d:f9:64:02:35:ed:49:81:76:04:30:a0:
98:cf:61:a8:71:3c:4f:e5:82:94:17:07:98:60:fe:2a:65:45:
24:07:ed:d8:2b:6f:b2:2e:c8:07:f3:74:ac:dc:70:28:37:2b:
4e:b8:6f:25:15:34:aa:1a:22:23:0c:e8:c9:5d:98:2b:98:0b:
44:60:23:cf:66:a3:2c:2f:38:bb:d9:f6:b5:2e:69:77:81:88:
63:7d:ec:dc:68:46:30:08:72:73:88:93:79:dc:d5:40:d2:aa:
83:d4:34:88:b5:62:f1:01:26:aa:48:a0:41:93:74:6a:51:60:
17:7a:f9:97:cb:92:a9:e1:cd:42:28:46:90:a1:f3:bc:68:c3:
d7:86:52:03:3f:90:b4:12:a3:c2:a2:ec:d3:ca:2b:56:89:11:
11:d8:fc:b5:8f:9d:72:30:e7:28:30:28:21:3f:58:64:24:57:
e0:c0:a6:2b:e9:ad:cc:56:1a:06:f8:5c:5e:ed:88:93:52:6d:
99:d0:dd:26:30:2a:82:05:f0:52:ac:e6:92:b0:44:e0:69:54:
6c:3d:8e:b5:cf:60:2c:87:52:0b:bf:ce:d7:2a:4a:71:c7:2e:
31:16:65:6b:0f:58:74:18:3a:7e:84:ef:94:47:a7:27:fd:20:
00:57:72:c5:ba:87:d3:90:89:01:21:29:37:55:bc:cd:43:41:
f3:97:69:c9:9e:e5:28:60:27:c0:c9:9a:0f:bd:5e:3f:14:b1:
92:f0:d8:14:42:c4:a9:89:4b:f3:5f:d4:8a:b8:2d:7a:7f:fb:
63:59:68:f0:ec:14:a4:73:22:64:c3:ac:73:4d:35:6c:fb:18:
40:a1:47:de:3e:fd:b8:43

2. Generate an SSL certificate signed by the custom Certificate Authority (CA)

2.1. Generate tls.key and tls.csr for the domain *.example.local.

# Generate tls.key and tls.csr for *.example.local domain.
# This command will create Subject Alternative Names (SANs) for 127.0.0.1, localhost, example.local, and *.example.local
openssl req -new -nodes -newkey rsa:4096 -keyout tls.key -out tls.csr -batch -subj "/C=LK/ST=Western Province/L=Colombo/O=Example (Private) Limited/OU=Development/CN=example.local" -reqexts SAN -config <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost,DNS:example.local,DNS:*.example.local"))

2.2. Generate and sign tls.crt for the domain *.example.local.

# Generate and sign tls.crt for the domain *.example.local
openssl x509 -req -in tls.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out tls.crt -days 3650 -sha256 -extfile <(printf "subjectAltName=IP:127.0.0.1,DNS:localhost,DNS:example.local,DNS:*.example.local")

2.3. Verify if the signed certificate is valid.

# Verify if the signed certificate is valid
openssl verify -verbose -CAfile ca.pem tls.crt

You shoud get an output like below.

tls.crt: OK

3. Add the custom CA certificate to OS Trust Store

# On CentOS
sudo cp ca.pem /etc/pki/ca-trust/source/anchors/ca.pem
sudo update-ca-trust

# On Ubuntu
sudo cp ca.pem /usr/local/share/ca-certificates/ca.pem
sudo update-ca-certificates

# On Windows
certutil.exe -addstore "Root" ca.pem

4. References

  1. Adding trusted root certificates to the server