如何在Linux Chrome和Firefox上信任自签名的localhost证书

fse*_*art 13 ssl firefox google-chrome localhost self-signed

我尝试为指向127.0.0.1的自定义本地域生成自签名证书:

# /etc/hosts
127.0.0.1 subdomain.domain.local
Run Code Online (Sandbox Code Playgroud)

我使用openssl并生成了一个自签名证书,并记住过去一切正常.但似乎自Chrome 58以来,使用自签名证书的限制要多得多.

我的尝试以" 您的连接不是私密 " 结束,并出现以下错误之一:

  • 如果我像过去一样继续," 安全证书不受信任 ".
  • 尝试将其导入Chrome时" 不是证书颁发机构 ".
  • 导入其CA后使用证书时" 主题备用名称丢失 ".

我很确定我在这个过程中遗漏了一些东西.请问,任何人都可以提供有效的配置来处理替代名称以及创建相应CA和证书的确切步骤,以便Chrome和Firefox可以处理我的本地自定义域吗?

lio*_*els 28

所有学分归Fabian Lee 撰写这篇优秀文章.

使用OpenSSL创建受信任的CA和SAN证书

  1. 自定义openssl.cnf
  2. 创建CA证书
  3. 使用CA签名的SAN创建服务器证书

条件

作为先决条件,请确保已安装SSL软件包:

#!/usr/bin/env bash
find . \( -name "$1.*" -o -name "*.srl" \) -type f -delete
cp /usr/lib/ssl/openssl.cnf $1.cnf
python <(
cat << "END"
import sys
from ConfigParser import ConfigParser
from StringIO import StringIO

domain = sys.argv[1]

config = ConfigParser()
config.optionxform = lambda option: option

name = "{}.cnf".format(domain)

with open(name, "rb") as stream:
  config.readfp(StringIO("[top]\n" + stream.read()))

config.set(" v3_ca ", "subjectKeyIdentifier", "hash")
config.set(" v3_ca ", "authorityKeyIdentifier", "keyid:always,issuer")
config.set(" v3_ca ", "basicConstraints", "critical, CA:TRUE, pathlen:3")
config.set(" v3_ca ", "keyUsage", "critical, cRLSign, keyCertSign")
config.set(" v3_ca ", "nsCertType", "sslCA, emailCA")

config.set(" v3_req ", "basicConstraints", "CA:FALSE")
config.set(" v3_req ", "keyUsage", "nonRepudiation, digitalSignature, keyEncipherment")
config.set(" v3_req ", "subjectAltName", "@alt_names")
config.remove_option(" v3_req ", "extendedKeyUsage")

config.add_section(" alt_names ")
config.set(" alt_names ", "DNS.1", domain)
config.set(" alt_names ", "DNS.2", "*.{}".format(domain))

config.set(" req ", "req_extensions", "v3_req")

with open(name, "wb") as stream:
    config.write(stream)
END
) $1
tail -n +2 $1.cnf > $1.cnf.tmp && mv $1.cnf.tmp $1.cnf
echo "$1\n" | openssl genrsa -aes256 -out $1.ca.key 2048
chmod 400 $1.ca.key
openssl req -new -x509 -subj "/CN=$1" -extensions v3_ca -days 3650 -key $1.ca.key -sha256 -out $1.ca.crt -config $1.cnf
openssl genrsa -out $1.key 2048
openssl req -subj "/CN=$1" -extensions v3_req -sha256 -new -key $1.key -out $1.csr
openssl x509 -req -extensions v3_req -days 3650 -sha256 -in $1.csr -CA $1.ca.crt -CAkey $1.ca.key -CAcreateserial -out $1.crt -extfile $1.cnf
openssl x509 -in $1.crt -text -noout
Run Code Online (Sandbox Code Playgroud)

定制openssl.cnf

第一步是获取generate.sh系统上可用的模板.在Ubuntu上可以找到./generate.sh example.com.您可以openssl.cnf在MacOS和/usr/lib/ssl/openssl.cnfRedhat变体上找到它.

$ sudo apt install libssl1.0.0 -y
Run Code Online (Sandbox Code Playgroud)

/System/Library/OpenSSL/ 需要使用有关我们将要生成的证书的特定信息进行修改.

在该/etc/pki/tls部分下,添加以下值.对于CA,这表示我们正在创建将用于密钥签名的CA.

export prefix="mydomain"

cp /usr/lib/ssl/openssl.cnf $prefix.cnf
Run Code Online (Sandbox Code Playgroud)

然后在该$prefix.cnf部分下,将以下内容与此证书的所有有效替代名称一起设置.

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical, CA:TRUE, pathlen:3
keyUsage = critical, cRLSign, keyCertSign
nsCertType = sslCA, emailCA
Run Code Online (Sandbox Code Playgroud)

同时取消注释该部分下面的行,[ v3_ca ]以便使用v3扩展创建证书请求.

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
#extendedKeyUsage=serverAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = mydomain.com 
DNS.2 = *.dydomain.com
Run Code Online (Sandbox Code Playgroud)

当我们生成每种类型的密钥时,我们指定要使用的扩展部分,这就是我们可以共享[ v3_req ]创建CA和SAN证书的原因.

创建CA证书

现在我们将开始使用OpenSSL来创建必要的密钥和证书.首先生成私有/公共RSA密钥对:

req_extensions = v3_req
Run Code Online (Sandbox Code Playgroud)

这使用基于AES256的密码对密钥文件进行编码.然后我们需要创建自签名的根CA证书.

openssl genrsa -aes256 -out ca.key.pem 2048

chmod 400 ca.key.pem
Run Code Online (Sandbox Code Playgroud)

您可以使用以下方法验证此根CA证书:

openssl req -new -x509 -subj "/CN=myca" -extensions v3_ca -days 3650 -key ca.key.pem -sha256 -out ca.pem -config $prefix.cnf
Run Code Online (Sandbox Code Playgroud)

这将显示根CA证书,并[ req ]$prefix.cnf将是相同的,因为这是自签名.这被标记为Issuer意味着它将被识别为根CA证书; 意味着浏览器和操作系统将允许将其导入其受信任的根证书存储区.

openssl x509 -in ca.pem -text -noout
Run Code Online (Sandbox Code Playgroud)

创建由CA签名的服务器证书

现在创建了根CA,我们切换到服务器证书.首先生成私有/公共RSA密钥对:

Issuer: CN=myca 
... 
Subject: CN=myca 
... 
X509v3 Basic Constraints: 
  critical CA:TRUE, pathlen:3 
X509v3 Key Usage: 
  critical Certificate Sign, CRL Sign 
Netscape Cert Type: 
  SSL CA, S/MIME CA
Run Code Online (Sandbox Code Playgroud)

我们没有在此密钥上加密码,因为CA是更有价值的目标,我们可以随时重新生成服务器证书,但请随意采取这一额外的预防措施.

然后创建服务器证书签名请求:

openssl genrsa -out $prefix.key.pem 2048
Run Code Online (Sandbox Code Playgroud)

然后使用以下命令生成服务器证书:服务器签名请求,CA签名密钥和CA证书.

openssl req -subj "/CN=$prefix" -extensions v3_req -sha256 -new -key $prefix.key.pem -out $prefix.csr
Run Code Online (Sandbox Code Playgroud)

Subject是服务器私钥,CA:TRUE是服务器证书.验证证书:

openssl x509 -req -extensions v3_req -days 3650 -sha256 -in $prefix.csr -CA ca.pem -CAkey ca.key.pem -CAcreateserial -out $prefix.crt -extfile $prefix.cnf
Run Code Online (Sandbox Code Playgroud)

这将显示证书,并且$prefix.key.pem将是CA名称,而Subject是前缀.这未设置为CA,该$prefix.crt字段包含浏览器认为有效的URL.

openssl x509 -in $prefix.crt -text -noout
Run Code Online (Sandbox Code Playgroud)

浏览器评估

当您首次使用带有CA签名的SAN证书在站点上指向Chrome或Firefox时,它将抛出与自签名SAN证书相同类型的例外.这是因为根CA证书不是已签名证书的可信来源.

Linux的

在Linux上,Chrome管理自己的证书存储区,您应该再次导入IssuerSubject Alternative Name.现在应该使安全图标变为绿色. 在此输入图像描述

视窗

在Chrome设置(ca.pem)中,搜索Authorities并点击chrome://settings.在Windows上,这将打开Windows证书管理器,您应该certificatesManage Certificates选项卡中导入该文件.这相当于ca.pemTrusted Root Certification Authorities受信任的根存储(不是计算机级别)中添加它.

火狐

在Firefox选项中mmc.exe,搜索local user并单击about:preferences.转到certificates选项卡并导入View Certificates.选中此框以使其信任网站,现在,当您访问该页面时,锁定图标应变为绿色. 在此输入图像描述

  • 在Ubuntu 16.04.3上,openssl和libssl的当前版本报告如下:X509 V3例程:v2i_GENERAL_NAME_ex:不受支持的选项:../ crypto / x509v3 / v3_alt.c:515:name = basicConstraints (2认同)