如何使浏览器信任本地主机SSL证书?

15

虽然存在类似的 问题,甚至有好的 答案, 但它们要么不涉及特定的localhost,要么只询问一个特定选项/解决方案(自签名vs CA)。

有哪些选项?它们如何比较?我该如何做到这一点?

3个回答

31

tl;dr 生成由自己的CA签发的证书(见下面的脚本)

以下是我找到的内容,如果有错误请指出。

有一些CA(证书颁发机构),它们为其他CA(中间CA)或服务器(终端实体证书)颁发证书(签署CSR)。其中一些是根CA。它们拥有由自己签署的自签名证书。通常情况下,从服务器证书到根证书有一条信任链。没有人为根证书提供担保。因此,操作系统具有根证书存储库(或信任策略存储库),即系统范围内的受信任根证书列表。浏览器有其自己的受信任证书列表,包括用户信任的证书。

在Chromium中,您可以在chrome://settings/certificates处管理证书。在Firefox中,选择“偏好设置>隐私与安全>证书>查看证书”。两者都有一个权限选项卡,其中列出了受信任的根证书。还有服务器选项卡,列出了受信任的服务器证书。

要获取证书,您需要创建CSR(证书签名请求),并将其发送给CA。 CA签署CSR,从而将其转换为可信证书。

证书和CSR是一些包含信息及公钥的字段。其中一些字段称为扩展名。CA证书是一个带有basicConstraints = CA:true的证书。

您可以在Chromium中的“开发人员工具>安全”中检查证书错误。

系统范围内信任证书

当您更改操作系统的根证书存储库时,必须重新启动浏览器。您可以使用以下命令更改它:

# trust anchor path/to/cert.crt
# trust anchor --remove path/to/cert.crt

trust命令将CA证书放在“authority”类别(trust list)中,否则放在“other-entry”类别中。CA证书出现在浏览器的Authorities标签中,或者出现在Servers标签。

与Chromium不同,Firefox不信任来自操作系统根证书存储的服务器证书。两者都信任来自操作系统根证书存储的CA证书。

在浏览器中信任证书

在Chromium和Firefox中,您可以将证书添加(导入)到Authorities标签中。如果您尝试导入非CA证书,您会收到“Not a Certificate Authority”消息。选择文件后,会出现一个对话框,您可以在其中指定信任设置(何时信任该证书)。使网站正常工作的相关设置是“Trust this certificate for identifying websites”。

在Chromium中,您可以将证书添加(导入)到Servers标签中。但它们最终会出现在Authorities标签(CA证书,并且在选择文件后不会显示信任设置对话框)或Others标签(如果非CA证书)。

在Firefox中,您无法完全将证书添加到Servers标签中。您需要添加异常。而且您可以在那里信任没有任何扩展名的证书(较差)。

自签名证书扩展

我的系统默认设置了以下证书的扩展名:

basicConstraints = critical,CA:true
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer

取自/etc/ssl/openssl.cnf,部分v3_ca。更多信息在此处

此外,当证书没有subjectAltName = DNS:$domain时,Chromium会认为该证书无效。

非自签名证书扩展

来自/etc/ssl/openssl.cnf[usr_cert]部分:

basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer

浏览器信任自签名证书

对于Chromium来说,要信任自签名证书必须具备basicConstraints = CA:truesubjectAltName = DNS:$domain。而对于Firefox来说,即使这些条件都满足也不够:

basicConstraints = critical,CA:true
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
subjectAltName = DNS:$domain

当浏览器信任由自己的CA颁发的证书时

Firefox不需要扩展,但Chromium需要使用subjectAltName

openssl速查表

openssl genpkey -algorithm RSA -out "$domain".key - 生成私钥(man

openssl req -x509 -key "$domain".key -out "$domain".crt - 生成自签名证书(man

如果没有-subj,它会询问有关区别名称(DN)的问题,例如常用名称(CN)、组织(O)、地点(L)。您可以提前回答它们:-subj "/CN=$domain/O=$org"

要添加subjectAltName扩展,您必须要么拥有指定了所有内容的配置文件,要么添加一个包含该扩展的部分到配置文件中,并使用-extensions开关告诉openssl它的名称:

    -config <(cat /etc/ssl/openssl.cnf - <<END
[ x509_ext ]
basicConstraints = critical,CA:true
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
subjectAltName = DNS:$domain
END
    ) -extensions x509_ext

openssl req -new -key "$domain".key -out "$domain".csr - 生成证书签名请求,可以使用-subj选项(man

openssl x509 -req -in "$domain".csr -days 365 -out "$domain".crt \ -CA ca.crt -CAkey ca.key -CAcreateserial - 签署证书签名请求(man

如果没有-CAcreateserial选项,则无法正常工作。它会创建一个ca.srl文件,其中保存了最后生成的证书的序列号。要添加subjectAltName,需要使用-extfile开关:

    -extfile <(cat <<END
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
subjectAltName = DNS:$domain
END
    )

openssl req -in $domain.csr -text -noout - 查看证书签名请求 (man)

openssl x509 -in $domain.crt -text -noout - 查看证书 (man)

生成自签名证书

(在Firefox中需要添加例外才能正常使用)

#!/usr/bin/env bash
set -eu
org=localhost
domain=localhost

sudo trust anchor --remove "$domain".crt || true

openssl genpkey -algorithm RSA -out "$domain".key
openssl req -x509 -key "$domain".key -out "$domain".crt \
    -subj "/CN=$domain/O=$org" \
    -config <(cat /etc/ssl/openssl.cnf - <<END
[ x509_ext ]
basicConstraints = critical,CA:true
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
subjectAltName = DNS:$domain
END
    ) -extensions x509_ext

sudo trust anchor "$domain".crt

生成由自己的CA颁发的证书

#!/usr/bin/env bash
set -eu
org=localhost-ca
domain=localhost

sudo trust anchor --remove ca.crt || true

openssl genpkey -algorithm RSA -out ca.key
openssl req -x509 -key ca.key -out ca.crt \
    -subj "/CN=$org/O=$org"

openssl genpkey -algorithm RSA -out "$domain".key
openssl req -new -key "$domain".key -out "$domain".csr \
    -subj "/CN=$domain/O=$org"

openssl x509 -req -in "$domain".csr -days 365 -out "$domain".crt \
    -CA ca.crt -CAkey ca.key -CAcreateserial \
    -extfile <(cat <<END
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
subjectAltName = DNS:$domain
END
    )

sudo trust anchor ca.crt

Web服务器配置

Nginx:

server {
    listen  443  ssl;
    ssl_certificate  ssl/localhost.crt;
    ssl_certificate_key  ssl/localhost.key;
    ...

Morbo:

carton exec morbo --listen='https://*:3000?cert=localhost.crt&key=localhost.key' \
    site.pl

P.S. 我正在运行 Chromium 65.0.3325.162,Firefox 59.0 和 openssl-1.1.0.g

Windows

显然,Windows 没有 trust 实用程序。在 Windows 下,有 两个存储:本地机器和当前用户证书存储。没有必要使用本地机器证书存储,因为我们只是为当前用户使其工作。然后,有子存储。其中两个预定义的最感兴趣:受信任的根证书颁发机构和中间证书颁发机构存储。通常在命令行中称为root 和 CA

您可以通过访问 chrome://settings/?search=Manage%20certificates,然后单击管理证书来访问 Chrome 的证书管理器。最感兴趣的是 受信任的根证书颁发机构 和 中间证书颁发机构选项卡。

管理证书的一种方式是通过 命令行

>rem list Current User > Trusted Root Certification Authorities store
>certutil.exe -store -user root

>rem list Local Machine > Intermediate Certification Authorities store
>certutil.exe -store -enterprise CA

>rem GUI version of -store command
>certutil.exe -viewstore -user CA

>rem add certificate to Current User > Trusted Root Certification Authorities store
>certutil.exe -addstore -user root path\to\file.crt

>rem delete certificate from Current User > Trusted Root Certification Authorities store by serial number
>certutil.exe -delstore -user root 03259fa1

>rem GUI version of -delstore command
>certutil.exe -viewdelstore -user CA

以下是结果(适用于本地计算机和当前用户证书存储):
root
    localhost.crt
        error
    ca.crt
        appears in Trusted Root Certification Authorities tab
CA
    localhost.crt
        doesn't work, appears in Other People tab
    ca.crt
        doesn't work, appears in Intermediate Certification Authorities tab

其他选项包括在资源管理器中双击证书、从Chrome的证书管理器导入证书、使用证书MMC插件(运行certmgr.msc)或使用CertMgr.exe

对于已安装grep的用户,快速检查证书位置的方法如下:

>certutil.exe -store -user root | grep "localhost\|^root\|^CA" ^
& certutil.exe -store -user CA | grep "locahost\|^root\|^CA" ^
& certutil.exe -store -enterprise root | grep "localhost\|^root\|^CA" ^
& certutil.exe -store -enterprise CA | grep "localhost\|^root\|^CA"

因此,将CA证书安装到当前用户>受信任的根证书颁发机构存储中似乎是最佳选择。而请确保不要忘记重新启动您的浏览器

额外阅读

OpenSSL
genpkey
req
x509
OpenSSL证书颁发机构
本地主机证书
iamaCA - 成为您自己的证书颁发机构并分发证书
Firefox和自签名证书
在Chrome中绕过证书错误页面


感谢您的工作。我是否正确理解,现在不可能创建一个单一的自签名证书,既满足Firefox又满足Chrome? - Oleg Neumyvakin
@OlegNeumyvakin 在“当浏览器信任自签名证书”中提到,Chrome可以信任自签名证书。而对于Firefox,如果我没记错的话,您可以添加一个例外。所以这可能是可能的。此外,您可能会发现easy-rsa项目很有趣。我在设置OpenVPN时遇到了它。它必须简化成为CA(特别是创建CA和服务器证书)的过程。虽然没有尝试过。 - x-yuri
这个代码片段也很有用:https://gist.github.com/mwidmann/115c2a7059dcce300b61f625d887e5dc - NAbdulla
这是一个经过深思熟虑的、优秀的答案。但在我的系统(Debian 11)上,某些部分似乎无法正常工作。获取证书输出中的扩展和SAN特别麻烦。这里发布的一些答案确实有效,可能对其他人有用:https://dev59.com/E77pa4cB1Zd3GeqPyWwQ#74802552 - JonathanDavidArndt

4

在 Chrome 上,可以浏览到 chrome://flags/#allow-insecure-localhost 并启用

允许从本地主机加载的资源使用无效证书。选项


这只是一个权宜之计或快速解决方案,适用于那些没有时间的人。我建议您转向此处接受的答案,因为它更具体、更安全,并且可以教您如何正确地完成它。 - Jos

0

您可以通过Microsoft Management Console在Windows中添加根CA证书。请按照以下步骤进行操作。

  • 登录Windows服务器。

  • 打开MMC。

  • 选择文件>添加/删除快捷方式。

  • 选择证书,然后选择添加。

  • 选择我的用户帐户。

  • 再次选择添加,这次选择计算机帐户。

  • 将新证书从“证书-当前用户>受信任的根证书颁发机构”移动到“证书(本地计算机)>受信任的根证书颁发机构”中。


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