如何在Linux Chrome和Firefox上信任自签名的本地主机证书

17

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

# /etc/hosts
127.0.0.1 subdomain.domain.local

我使用openssl生成了一个自签名证书,并记得过去一切都运行正常。但是自Chrome 58以来,似乎对使用自签名证书有更多的限制。

我的尝试以"您的连接不是私密的"告终,随后出现以下错误之一:

  • 如果像以前那样继续进行,则为"安全证书不受信任"。
  • 在尝试导入到Chrome时为"不是认证机构"。
  • 在导入其CA后使用证书时为"缺少主体替代名称"。

我很确定在这个过程中漏掉了什么。请问有人能够提供有效的配置,处理备选名称以及创建相应CA和证书的确切步骤,以便Chrome和Firefox可以处理我的本地自定义域名吗?

1个回答

38

简述

  1. 创建文件generate.sh

#!/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
  • 运行命令 ./generate.sh example.com

    需要 Python 2


  • 本文所有内容均来自Fabian Lee的优秀文章

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

    1. 自定义 openssl.cnf 文件
    2. 创建 CA 证书
    3. 创建由 CA 签名的带有 SAN 的服务器证书

    先决条件

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

    $ sudo apt install libssl1.0.0 -y
    

    自定义openssl.cnf

    第一步是获取您系统上可用的 openssl.cnf 模板。在Ubuntu上,可以在/usr/lib/ssl/openssl.cnf找到它。在MacOS上可能会在/System/Library/OpenSSL/中找到,而在Redhat变体上则可能会在/etc/pki/tls中找到。

    export prefix="mydomain"
    
    cp /usr/lib/ssl/openssl.cnf $prefix.cnf
    

    $prefix.cnf需要被修改,以包含关于我们将要生成的证书的具体信息。

    [v3_ca]部分下,添加以下值。对于CA来说,这表示我们正在创建一个用于密钥签名的CA。

    [ v3_ca ]
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid:always,issuer
    basicConstraints = critical, CA:TRUE, pathlen:3
    keyUsage = critical, cRLSign, keyCertSign
    nsCertType = sslCA, emailCA
    

    然后,在[ v3_req ]部分中,除了此证书的所有有效替代名称外,设置以下内容。

    [ v3_req ]
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    #extendedKeyUsage=serverAuth
    subjectAltName = @alt_names
    
    [ alt_names ]
    DNS.1 = mydomain.com 
    DNS.2 = *.dydomain.com
    

    同时取消注释下面语句,位于[ req ] 部分下方,这样证书请求将会创建具有 v3 扩展的证书。

    req_extensions = v3_req
    

    在生成每种类型的密钥时,我们需要指定要使用哪个扩展部分,这就是为什么我们可以共用$prefix.cnf来创建CA证书和SAN证书的原因。

    创建CA证书

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

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

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

    openssl req -new -x509 -subj "/CN=myca" -extensions v3_ca -days 3650 -key ca.key.pem -sha256 -out ca.pem -config $prefix.cnf
    

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

    openssl x509 -in ca.pem -text -noout
    

    这将显示根CA证书,颁发者主题将是相同的,因为这是自签名的。这被标记为CA:TRUE表示它将被识别为根CA证书; 这意味着浏览器和操作系统将允许将其导入到他们的受信任根证书存储中。

    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
    

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

    现在已经创建了根CA,我们转向服务器证书。首先生成私钥/公钥RSA密钥对:

    openssl genrsa -out $prefix.key.pem 2048
    

    我们没有在该密钥上设置密码,仅仅因为CA更有价值的目标,我们随时可以重新生成服务器证书,但是如果您希望采取这种额外预防措施,请随意这样做。

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

    openssl req -subj "/CN=$prefix" -extensions v3_req -sha256 -new -key $prefix.key.pem -out $prefix.csr
    

    然后使用服务器签名请求、CA签名密钥和CA证书生成服务器证书。

    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
    

    $prefix.key.pem 是服务器私钥,$prefix.crt 是服务器证书。验证该证书:

    openssl x509 -in $prefix.crt -text -noout
    

    这将显示证书,Issuer 是证书颁发机构名称,而 Subject 则是前缀。该证书不被设置为 CA,并且 Subject Alternative Name 字段包含浏览器认为有效的 URL。

    Issuer: 
     CN=myca 
    ... 
    Subject: 
      CN=mydomain 
    ... 
    X509v3 Basic Constraints: 
      CA:FALSE 
    X509v3 Key Usage: 
      Digital Signature, Non Repudiation, Key Encipherment 
    X509v3 Subject Alternative Name:
      DNS:mydomain.com, DNS:*.mydomain.com
    

    浏览器验证

    当您首次使用Chrome或Firefox访问使用CA签名的SAN证书的网站时,它将抛出与自签名SAN证书相同类型的异常。这是因为根CA证书不被认为是签名证书的可信来源。

    Chrome

    Linux

    在Linux上,Chrome管理自己的证书存储,并且您应该将ca.pem导入到Authorities中。这应该会使安全图标变成绿色。 enter image description here

    Windows

    在Chrome设置(chrome://settings)中,搜索certificates并单击Manage Certificates。在Windows上,这将打开Windows证书管理器,您应该在Trusted Root Certification Authorities选项卡中导入ca.pem文件。这相当于通过mmc.exe添加它,在本地用户受信任的根存储区域(而不是计算机级别)中。

    Firefox

    在Firefox选项about:preferences中,搜索certificates并单击View Certificates。转到Authorities选项卡并导入ca.pem。选中信任网站的框,并且现在当您访问该页面时,锁定图标应变为绿色。 enter image description here


    2
    在Ubuntu 16.04.3上,当前版本的openssl和libssl报告如下: X509 V3例程:v2i_GENERAL_NAME_ex:不支持选项:../crypto/x509v3/v3_alt.c:515:name=basicConstraints - Greg Bell
    @GregBell 我编辑了答案以修复这个错误。基本上,可用的alt_names键在此处列出:https://github.com/openssl/openssl/blob/master/crypto/x509v3/v3_alt.c#L500 - MakotoE
    永久链接:https://github.com/openssl/openssl/blob/bcf082d130a413a728a382bd6e6bfdbf2cedba45/crypto/x509v3/v3_alt.c#L500 - MakotoE
    在CA证书上是否必须设置密码短语? - Ben Davis

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接