Create self signed certificate with subjectAltName to fix [missing_subjectAltName] in Chrome 58+

I'm trying to create a self signed certificate for localhost containing subjectAltName to satisfy Chrome 58+:

createcertificate.sh:

#!/usr/bin/env bash
filename="$1server"
openssl req -new -sha256 -nodes -out ./../nginx/ssl/${filename}.csr -newkey rsa:2048 -keyout ./../nginx/ssl/${filename}.key -config <( cat ${filename}_csr.txt )
openssl x509 -req -in ./../nginx/ssl/${filename}.csr -CA ~/ssl/rootCA.pem -CAkey ~/ssl/rootCA.key -CAcreateserial -out ./../nginx/ssl/${filename}.crt -days 500 -sha256

server_csr.txt:

[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C=US
ST=New York
L=Rochester
O=End Point
OU=Testing Domain
emailAddress=
CN = localhost
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = localhost

Call ./createcertificate.sh:

server_csr.txt
Generating a 2048 bit RSA private key
.........................................................................................................+++
...............................+++
writing new private key to './../nginx/ssl/server.key'
-----
Signature ok
subject=/C=US/ST=New York/L=Rochester/O=End Point/OU=Testing Domain/emailAddress=your-administrative-address@
Getting CA Private Key
Enter pass phrase for /home/alexzeitler/ssl/rootCA.key:

But Chrome 58 still refuses the certificate:

This server could not prove that it is localhost; its security certificate is from [missing_subjectAltName]. This may be caused by a misconfiguration or an attacker intercepting your connection. 

This is the output of openssl req -in ../nginx/ssl/server.csr -noout -text:

Certificate Request: Data: Version: 0 (0x0) Subject: C=US, ST=New York, L=Rochester, O=End Point, OU=Testing Domain/emailAddress=, CN=localhost Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:cf:ec:6d:54:6e:db:e0:9c:cd:17:c2:dd:bf:81: 1e:52:bb:62:27:04:f3:13:8e:01:69:47:fa:93:92: 57:b3:77:be:51:87:9b:c8:40:f1:28:de:df:cb:d2: fd:87:fb:00:a1:c4:17:30:4c:9a:fd:e0:b6:d0:8c: a0:c9:01:f4:71:5f:63:ee:6d:4c:5a:b4:4d:ca:60: d4:0b:dc:6f:c1:2b:62:95:44:76:ec:45:bf:cb:39: 4a:0a:e4:f7:84:56:d0:1b:11:2c:e7:a8:b6:f6:bc: 46:89:bb:4b:44:3c:7d:9d:d8:cc:75:4c:4c:72:15: b4:58:77:9b:38:61:72:4c:b2:45:55:a2:34:06:aa: 4c:9d:54:cb:a4:bf:58:26:88:11:81:17:a3:52:ab: c8:38:f7:c5:55:78:af:d3:be:3f:70:95:79:d9:79: 10:45:5f:e9:10:e9:56:6f:b5:fa:b9:36:2e:c8:40: c5:fa:86:66:12:82:ec:ab:45:75:54:ec:93:40:9f: d1:cc:8f:18:31:8b:62:1c:20:da:6e:19:17:89:c5: 6f:c5:b9:23:a0:86:6e:70:f9:2a:b1:e3:87:dc:a2: 57:99:16:05:d4:85:01:43:34:48:d5:b4:39:35:63: 46:81:d2:f1:b8:66:e2:21:31:c3:8a:02:f7:8f:a9: b4:8b Exponent: 65537 (0x10001) Attributes: Requested Extensions: X509v3 Subject Alternative Name: DNS:localhost Signature Algorithm: sha256WithRSAEncryption 60:d7:11:95:45:9b:b6:35:ed:b7:31:2b:14:5d:c7:57:bb:cd: fc:3b:c4:97:01:aa:46:4c:58:9b:f8:4c:44:e2:12:46:2d:69: 5f:95:10:02:fd:79:e1:30:cb:a9:f9:41:b2:a7:b6:fa:e3:2f: e9:c6:7c:3e:3a:b1:db:64:b9:6e:ab:a1:98:82:0c:df:cf:b5: e9:7f:17:f0:87:c9:09:15:ab:c8:9b:a2:d8:b3:37:a8:13:2e: 05:f5:ab:18:4c:cf:d9:6d:d0:05:c4:90:b5:0e:a5:c2:24:6d: 12:fb:e1:64:5c:d0:6f:5a:86:a3:d2:1f:b8:73:12:1e:39:28: a9:50:a4:88:fb:e6:24:95:17:43:76:22:7d:57:48:af:84:36: 66:30:d8:3b:88:3b:4c:c5:44:fc:92:75:16:b6:9a:22:4b:cf: b2:9b:19:e2:15:d4:9c:04:85:8d:7a:59:f7:13:7c:be:d4:4f: c5:d8:02:79:ab:98:3f:91:0e:da:ba:8b:68:01:d3:71:cb:f0: 55:22:fe:f8:55:41:ef:ac:f4:55:48:06:ce:75:ba:33:5c:b2: 7b:f3:a7:b4:c3:ec:c0:52:ec:e1:56:64:84:cb:fa:a1:ca:0c: c0:c3:87:e4:f4:c1:5b:8b:92:00:26:9d:a8:6b:35:58:1f:ad: 9e:91:ba:5b

Thus, the Subject Alternative Name information seems to exist in the csr.

On the other hand openssl x509 -text -in ../nginx/ssl/server.crt -noout outputs:

Certificate: Data: Version: 1 (0x0) Serial Number: 17237690484651272010 (0xef38942aa5c5274a) Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, ST=New York, L=Rochester, O=End Point, CN=localhost/emailAddress= Validity Not Before: Apr 23 15:42:28 2017 GMT Not After : Sep 5 15:42:28 2018 GMT Subject: C=US, ST=New York, L=Rochester, O=End Point, OU=Testing Domain/emailAddress=, CN=localhost Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:af:ee:7c:7a:2c:3c:5c:a6:57:ce:81:cf:22:49: 3c:d3:c4:6d:3a:71:a8:c7:cf:04:cc:68:4a:e6:03: 7c:9d:9d:49:c7:4f:8e:33:09:5b:73:9b:a0:21:51: 27:c6:e6:d0:ac:f5:5e:1d:4f:f8:60:9f:a1:50:1e: dd:1f:bc:20:44:6f:42:c8:de:2a:6f:04:b7:21:aa: cb:82:18:5e:fa:d8:68:5d:e5:c6:a0:cb:39:e3:91: 60:99:3f:ae:63:ab:9c:23:e9:03:0c:ca:10:23:8f: 76:e1:5c:55:10:b7:e1:e7:aa:e7:24:4d:49:ff:d0: c7:67:f6:8a:1d:36:12:15:49:2d:33:c9:39:d4:3f: 7f:b6:a5:9e:ac:b5:55:75:aa:bc:7f:f4:c2:85:b4: 18:f1:76:3c:5e:a3:df:47:00:1c:e6:ac:d5:3c:f3: ac:ff:f2:f0:7a:43:3f:63:bd:77:86:ea:3f:e5:35: 04:fa:3c:2a:0c:34:b5:36:ee:a0:b2:50:f9:08:31: b8:76:27:af:c7:c6:5a:af:52:07:6f:c3:d6:6c:97: 6b:9b:cb:cd:c7:01:4f:33:7e:2f:09:06:b0:71:1a: 9a:9f:30:d4:c3:67:89:15:dc:df:ad:68:44:54:29: 26:d0:ca:8e:f6:eb:dd:f3:1a:74:63:89:b4:c5:72: 82:af Exponent: 65537 (0x10001) Signature Algorithm: sha256WithRSAEncryption 42:f7:c4:1e:47:dc:e7:81:3a:b0:83:a8:fd:51:53:32:f7:80: 76:b4:ec:a8:44:17:5a:18:29:68:9f:14:4a:1c:35:87:3e:7a: 13:95:0c:8b:5b:2f:f9:f0:42:56:51:9c:a9:9f:7f:77:45:7d: 6c:1d:1c:39:75:99:4a:c5:22:c4:d9:1d:11:bb:bf:7d:56:7b: a7:18:fc:2a:c3:32:c1:72:3a:17:0e:1d:27:f1:f3:b6:72:91: 5d:38:64:6c:98:03:8b:17:88:ce:2c:a2:dc:2a:86:a0:e8:23: e8:07:79:ac:05:62:b1:17:10:84:82:02:23:4a:10:9a:2a:b3: 9c:5d:05:71:31:43:f3:28:4e:28:bd:31:49:21:1f:39:b0:6b: 39:27:1c:1a:8e:b8:92:e9:e7:76:a2:e7:3e:6c:ba:fc:56:f1: 78:85:3f:68:ea:db:50:88:b4:8a:fc:ea:73:04:4b:8a:54:86: 5e:0d:fc:b4:70:72:c9:5a:c7:cf:cb:19:e2:9a:b9:af:c6:3e: 55:06:1c:7c:62:44:b3:e6:57:2b:0f:cc:33:9e:28:5f:62:85: 05:27:4c:f0:de:6c:d6:fb:e4:de:2f:41:99:34:b2:b1:7d:12: b6:d6:96:a5:4b:c4:49:6b:49:bf:c5:86:e6:3c:3e:f3:e3:ef: a9:d3:21:5e

The .crt doesn't contain the Subject Alternative Name.

3

4 Answers

While reading the documentation for subjectAltName, I noticed, that my certificate has shown Version: 1 while the documentation show Version: 3.

To get a Version 3 certificate, I specified the -extfile option:

sudo openssl x509 -req -in ./../nginx/ssl/${filename}.csr -CA ~/ssl/rootCA.pem -CAkey ~/ssl/rootCA.key -CAcreateserial -out ./../nginx/ssl/${filename}.crt -days 500 -sha256 -extfile v3.ext

v3.ext looks like this:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost

When running openssl x509 -text -in ../nginx/ssl/server.crt -noout again, the certificate now also contains the Subject Alternative Name section:

Certificate: Data: Version: 3 (0x2) Serial Number: 17237690484651272016 (0xef38942aa5c52750) Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, ST=New York, L=Rochester, O=End Point, CN=localhost/ Validity Not Before: Apr 23 16:07:38 2017 GMT Not After : Sep 5 16:07:38 2018 GMT Subject: C=US, ST=New York, L=Rochester, O=End Point, OU=Testing Domain/emailAddress=, CN=localhost Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:b2:e3:bd:ed:28:04:85:ea:75:ee:d2:82:e1:eb: f5:5f:7f:cf:7e:cb:70:de:86:9f:75:7c:f3:71:e7: da:16:fb:bc:1f:89:bc:47:08:77:ca:33:20:f1:c1: 9e:e3:20:8d:89:14:7e:c1:0a:12:d2:59:24:56:9b: 77:90:5f:69:d1:a5:f1:00:38:93:1b:a7:75:f1:33: e2:da:dc:32:a9:0a:85:7d:9a:20:81:ca:20:ee:86: ce:e2:a0:52:d2:ab:11:34:e5:52:99:3a:81:c6:9f: 6b:0f:6a:02:2b:38:a6:84:c9:ba:fa:9b:ef:0a:89: 22:4b:79:86:3c:bd:44:a5:54:fb:cf:4d:8b:d1:44: 03:35:22:de:69:77:c8:fa:4d:c6:01:25:08:9f:4d: a9:79:7a:aa:ca:03:b6:e4:51:57:22:27:5f:a7:12: 11:f3:e6:00:29:f6:58:be:2c:aa:09:e4:06:45:d9: 3f:75:a7:f0:75:bd:2b:a6:bb:6d:ad:93:bb:b9:1d: d7:75:39:4e:9b:1d:0e:39:cc:17:74:88:f7:e2:b7: 85:12:96:e0:cb:42:56:d0:11:e0:84:86:e5:14:a5: f2:6d:43:5d:f9:59:ae:61:7f:01:ae:95:b8:92:27: 1d:1c:02:d7:ad:fb:ee:f6:25:38:60:c8:41:20:17: 80:69 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:5A:8D:89:64:BD:F2:3E:C2:D7:7B:BE:17:84:F4:29:E8:C5:32:35:34 X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment X509v3 Subject Alternative Name: DNS:localhost Signature Algorithm: sha256WithRSAEncryption 27:1d:d6:84:50:33:d2:ff:b1:06:9b:fa:f1:40:7d:47:11:bc: f7:80:fd:26:87:0e:91:9f:14:be:1f:1d:9b:32:d1:fb:d6:8d: af:30:8a:88:38:8c:1c:bf:77:98:8e:cd:06:48:82:fa:09:b9: 3c:0d:38:c4:a0:da:b7:4d:f5:81:5f:5a:76:04:61:f8:c2:1a: 17:ad:56:7c:72:ba:f6:65:7f:7f:e7:5e:b2:34:ba:13:23:57: 84:f1:c5:ca:dd:5b:55:69:95:71:44:4a:30:53:61:5c:ad:47: d8:9c:d5:a2:1b:18:2d:e1:19:35:3e:3f:b2:7e:fd:bf:f3:d0: 45:dc:f5:57:f0:1b:cd:70:1b:e0:34:de:27:98:89:b4:a5:25: a5:6c:29:c3:89:a6:a5:c5:4d:f5:45:3b:47:8e:13:45:23:07: 5e:d6:59:0d:96:c6:a3:f0:c5:3d:ee:a8:ad:36:96:43:13:a1: b8:55:f6:c7:10:7e:8f:5d:09:ef:61:17:2a:9c:3b:50:28:c8: e3:8d:a6:34:06:50:d4:3e:d5:17:ea:7d:31:97:d3:ee:df:b5: 23:66:5e:22:b7:e4:fa:36:4f:9a:d5:f0:a3:f9:b4:2b:27:02: 0b:41:94:d1:a1:f7:1b:2c:7e:74:e6:14:c3:b5:67:15:d2:ca: 02:77:57:a6

I also created a blog post.

If you want to add 127.0.0.1, you must write:

[alt_names]
IP.1 = 127.0.0.1

If you add DNS.1 = 127.0.0.1 Chrome will return a ERR_CERT_COMMON_NAME_INVALID.

Thanks to @Robar for pointing this out in the comments.

4

In Windows, save this script in your SSL folder as makeCert.bat. The self-signed certificate it makes will satisfy Chrome ver 58+ requirement for SAN (Subject Alternative Name).

This script will create these files: example.cnf, example.crt, example.key

@echo off
REM IN YOUR SSL FOLDER, SAVE THIS FILE AS: makeCert.bat
REM AT COMMAND LINE IN YOUR SSL FOLDER, RUN: makecert
REM IT WILL CREATE THESE FILES: example.cnf, example.crt, example.key
REM IMPORT THE .crt FILE INTO CHROME Trusted Root Certification Authorities
REM REMEMBER TO RESTART APACHE OR NGINX AFTER YOU CONFIGURE FOR THESE FILES
REM PLEASE UPDATE THE FOLLOWING VARIABLES FOR YOUR NEEDS.
SET HOSTNAME=example
SET DOT=com
SET COUNTRY=US
SET STATE=KS
SET CITY=Olathe
SET ORGANIZATION=IT
SET ORGANIZATION_UNIT=IT Department
SET EMAIL=webmaster@%HOSTNAME%.%DOT%
(
echo [req]
echo default_bits = 2048
echo prompt = no
echo default_md = sha256
echo x509_extensions = v3_req
echo distinguished_name = dn
echo:
echo [dn]
echo C = %COUNTRY%
echo ST = %STATE%
echo L = %CITY%
echo O = %ORGANIZATION%
echo OU = %ORGANIZATION_UNIT%
echo emailAddress = %EMAIL%
echo CN = %HOSTNAME%.%DOT%
echo:
echo [v3_req]
echo subjectAltName = @alt_names
echo:
echo [alt_names]
echo DNS.1 = *.%HOSTNAME%.%DOT%
echo DNS.2 = %HOSTNAME%.%DOT%
)>%HOSTNAME%.cnf
openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout %HOSTNAME%.key -days 3560 -out %HOSTNAME%.crt -config %HOSTNAME%.cnf
2

I updated STWilson's batch file to remove the COM stuff since localhost doesn't really have that and I want a self-signed localhost SSL certificate for development. I also added a few additional files like a .pfx and .pem.key file.

@echo off
REM IN YOUR SSL FOLDER, SAVE THIS FILE AS: makeCert.bat
REM AT COMMAND LINE IN YOUR SSL FOLDER, RUN: makecert
REM IT WILL CREATE THESE FILES: example.cnf, example.crt, example.key
REM IMPORT THE .crt FILE INTO CHROME Trusted Root Certification Authorities
REM REMEMBER TO RESTART APACHE OR NGINX AFTER YOU CONFIGURE FOR THESE FILES
REM PLEASE UPDATE THE FOLLOWING VARIABLES FOR YOUR NEEDS.
SET HOSTNAME=example
SET COUNTRY=US
SET STATE=KS
SET CITY=Olathe
SET ORGANIZATION=IT
SET ORGANIZATION_UNIT=IT Department
SET EMAIL=
(
echo [req]
echo default_bits = 2048
echo prompt = no
echo default_md = sha256
echo x509_extensions = v3_req
echo distinguished_name = dn
echo:
echo [dn]
echo C = %COUNTRY%
echo ST = %STATE%
echo L = %CITY%
echo O = %ORGANIZATION%
echo OU = %ORGANIZATION_UNIT%
echo emailAddress = %EMAIL%
echo CN = %HOSTNAME%
echo:
echo [v3_req]
echo subjectAltName = @alt_names
echo:
echo [alt_names]
echo DNS.1 = *.%HOSTNAME%
echo DNS.2 = %HOSTNAME%
)>%HOSTNAME%.cnf
REM MAKE THE .key .crt AND .cnf FILES
openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout %HOSTNAME%.key -days 3560 -out %HOSTNAME%.crt -config %HOSTNAME%.cnf
REM MAKE THE .pfx FILE
openssl pkcs12 -export -out %HOSTNAME%.pfx -inkey %HOSTNAME%.key -in %HOSTNAME%.crt
REM MAKE THE .pem.key FILE
openssl rsa -in %HOSTNAME%.key -outform PEM -out %HOSTNAME%.pem.key
1

Stuff like this always goes in /usr/local/bin.

I got this from

#! /bin/bash
mkdir /tmp/scert 2>/dev/null
rm -r /tmp/scert/* 2>/dev/null
if [ $# -ne 1 ];
then echo "Usage: scert <name>" exit
fi
if [ -e "/etc/ssl/private/$1.key" ];
then echo "/etc/ssl/private/$1.key already exists" exit
fi
if [ -e "/etc/ssl/certs/$1.crt" ];
then echo "/etc/ssl/certs/$1.crt already exists" exit
fi
if [ -e "/etc/ssl/certs/$1.pem" ];
then echo "/etc/ssl/certs/$1.pem already exists" exit
fi
echo "[req]" > /tmp/scert/tmp.cnf
echo "default_bits = 2048" >> /tmp/scert/tmp.cnf
echo "prompt = no" >> /tmp/scert/tmp.cnf
echo "default_md = sha256" >> /tmp/scert/tmp.cnf
echo "distinguished_name = dn" >> /tmp/scert/tmp.cnf
echo "" >> /tmp/scert/tmp.cnf
echo "[dn]" >> /tmp/scert/tmp.cnf
echo "C=US" >> /tmp/scert/tmp.cnf
echo "ST=New York" >> /tmp/scert/tmp.cnf
echo "L=Rochester" >> /tmp/scert/tmp.cnf
echo "O=$1" >> /tmp/scert/tmp.cnf
echo "OU=Testing Domain" >> /tmp/scert/tmp.cnf
echo "emailAddress=" >> /tmp/scert/tmp.cnf
echo "CN = localhost" >> /tmp/scert/tmp.cnf
echo "authorityKeyIdentifier=keyid,issuer" > /tmp/scert/tmp.ext
echo "basicConstraints=CA:FALSE" >> /tmp/scert/tmp.ext
echo "keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment" >> /tmp/scert/tmp.ext
echo "subjectAltName = @alt_names" >> /tmp/scert/tmp.ext
echo "" >> /tmp/scert/tmp.ext
echo "[alt_names]" >> /tmp/scert/tmp.ext
echo "DNS.1 = localhost" >> /tmp/scert/tmp.ext
openssl genrsa -des3 -passout pass:x -out /tmp/scert/tmp.pass.key 2048
openssl rsa -passin pass:x -in "/tmp/scert/tmp.pass.key" -out "/tmp/scert/tmp.key"
openssl req -x509 -new -nodes -key /tmp/scert/tmp.key -subj "/C=US/ST=New York/L=Rochester/O=$1/OU=Testing Domain/CN=localhost" -sha256 -days 1024 -out /tmp/scert/$1.pem
openssl req -new -sha256 -nodes -out /tmp/scert/tmp.csr -newkey rsa:2048 -keyout /tmp/scert/$1.key -config <( cat /tmp/scert/tmp.cnf )
openssl x509 -req -in /tmp/scert/tmp.csr -CA /tmp/scert/$1.pem -CAkey /tmp/scert/tmp.key -CAcreateserial -out /tmp/scert/$1.crt -days 500 -sha256 -extfile /tmp/scert/tmp.ext
if [ -e "/tmp/scert/$1.key" ];
then sudo cp /tmp/scert/$1.key /etc/ssl/private sudo chown root:ssl-cert /etc/ssl/private/$1.key sudo chmod 640 /etc/ssl/private/$1.key ls -al /etc/ssl/private/$1.key
else echo "ERROR: /tmp/scert/$1.key not found"
fi
if [ -e "/tmp/scert/$1.crt" ];
then sudo cp /tmp/scert/$1.crt /etc/ssl/certs sudo chown root:root /etc/ssl/certs/$1.crt sudo chmod 755 /etc/ssl/certs/$1.crt ls -al /etc/ssl/certs/$1.crt
else echo "ERROR: /tmp/scert/$1.crt not found"
fi
if [ -e "/tmp/scert/$1.pem" ];
then sudo cp /tmp/scert/$1.pem /etc/ssl/certs sudo chown root:root /etc/ssl/certs/$1.pem sudo chmod 755 /etc/ssl/certs/$1.pem ls -al /etc/ssl/certs/$1.pem
else echo "ERROR: /tmp/scert/$1.pem not found"
fi
rm -r /tmp/scert/* 2>/dev/null

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like