使 Chrome 接受自签名的本地主机证书

我已经为本地主机 CN 创建了一个自签名 SSL 证书。如预期的那样,Firefox 在最初抱怨它之后接受了该证书。但是,即使将证书添加到 “受信任的根” 下的系统证书存储中,Chrome 和 IE 也拒绝接受它。即使我在 Chrome 的 HTTPS 弹出窗口中单击 “查看证书信息” 时列出的证书已正确安装,它仍然坚持认为证书不可信任。

我应该怎么做才能让 Chrome 接受证书并停止抱怨呢?

答案

仅适用于localhost

只需将其粘贴到您的 Chrome 中:

chrome://flags/#allow-insecure-localhost

您应该看到突出显示的文字:允许从本地主机加载的资源使用无效证书

点击Enable

这为我工作:

  1. 使用 Chrome 浏览器,通过 HTTPS 在服务器上点击一个页面,然后继续经过红色警告页面(假设您尚未执行此操作)。
  2. 打开Chrome Settings > Show advanced settings > HTTPS/SSL > Manage Certificates
  3. 单击 “ Authorities选项卡,然后向下滚动以在您授予证书的组织名称下找到您的证书。
  4. 选择它,然后单击 “编辑”( 注意 :在最新版本的 Chrome 中,该按钮现在为 “高级”,而不是 “编辑”),选中所有复选框,然后单击 “确定”。您可能必须重新启动 Chrome。

您现在应该在页面上看到漂亮的绿色锁。

编辑:我在新计算机上再次尝试了此操作,仅通过从红色不受信任的证书页面继续进行操作,证书就没有出现在 “管理证书” 窗口中。我必须执行以下操作:

  1. 在带有不受信任的证书的页面上( https://标记为红色),单击锁 > 证书信息。 注意:在较新版本的 chrome 上,您必须打开Developer Tools > Security ,然后选择View certificate
  2. 单击Details tab > Export 。选择PKCS #7, single certificate作为文件格式。
  3. 然后按照我的原始说明进入 “管理证书” 页面。单击Authorities tab > Import然后选择将证书导出到的文件,并确保选择 PKCS #7, single certificate 作为文件类型
  4. 如果提示存储证书,请选择 “ 受信任的根证书颁发机构”
  5. 选中所有框,然后单击确定。重新启动 Chrome。

CHROME 58 + 的更新(已发布 2017-04-19)

从 Chrome 58 开始, 删除了仅使用commonName标识主机的功能。证书现在必须使用subjectAltName来标识其主机。 在此处查看更多讨论,在此处查看错误跟踪器 。过去, subjectAltName仅用于多主机证书,因此某些内部 CA 工具不包含它们。

如果您的自签名证书过去运行良好,但突然开始在 Chrome 58 中生成错误,这就是原因。

因此,无论您使用哪种方法生成自签名证书(或由自签名 CA 签名的证书), subjectAltName确保服务器的证书包含带有正确DNS和 / 或IP条目 / 条目的subjectAltName即使仅用于一个主机

对于 openssl,这意味着您的 OpenSSL 配置 (在 Ubuntu 上为/etc/ssl/openssl.cnf )对于单个主机应该具有类似于以下内容:

[v3_ca]   # and/or [v3_req], if you are generating a CSR
subjectAltName = DNS:example.com

或多个主机:

[v3_ca]   # and/or [v3_req], if you are generating a CSR
subjectAltName = DNS:example.com, DNS:host1.example.com, DNS:*.host2.example.com, IP:10.1.2.3

在 Chrome 的证书查看器(已移至 F12 下的 “安全” 标签)中,您应该看到它在 “ Extensions为 “ Certificate Subject Alternative Name

Chrome证书查看器

在 Mac 上,您可以使用 “钥匙串访问” 实用程序将自签名证书添加到 “系统” 钥匙串中,然后 Chrome 会接受它。我在这里找到了分步说明:

Google Chrome,Mac OS X 和自签名 SSL 证书

基本上:

  1. 双击带有 X 的锁图标,然后将证书图标拖放到桌面上,
  2. 打开此文件(扩展名为. cer);这将打开钥匙串应用程序,使您可以批准证书。

单击页面上的任意位置,然后键入 BYPASS_SEQUENCE

thisisunsafe ” 是适用于 Chrome 65 版的 BYPASS_SEQUENCE

badidea ” Chrome 版本badidea

在过去的 Chrome 版本中使用 “ danger

您无需查找输入字段,只需键入它即可。感觉很奇怪,但是正在工作。

我在 Mac High Sierra 上尝试过。

要再次检查他们是否再次更改,请转到最新的铬源代码

要查找 BYPASS_SEQUENCE,目前看起来像这样:

var BYPASS_SEQUENCE = window.atob('dGhpc2lzdW5zYWZl');

现在,它们已经被伪装了,但是要查看真正的 BYPASS_SEQUENCE,您可以在浏览器控制台中运行以下代码。

console.log(window.atob('dGhpc2lzdW5zYWZl'));

的 Linux

如果您使用的是 Linux,则还可以遵循以下官方 Wiki 页面:

基本上:

  • 点击带有 X 的锁形图标,
  • 选择证书信息
  • 转到详细信息选项卡
  • 单击导出...(另存为文件)

现在,以下命令将添加证书(其中 YOUR_FILE 是您的导出文件):

certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n YOUR_FILE -i YOUR_FILE

要列出所有证书,请运行以下命令:

certutil -d sql:$HOME/.pki/nssdb -L

如果仍然无法正常工作,则可能会受到以下错误的影响: 问题 55050:Ubuntu SSL 错误 8179

注意:在使用上述命令之前,请确保您具有libnss3-tools

如果没有,请通过以下方式安装:

sudo apt-get install libnss3-tools # on Ubuntu
sudo yum install nss-tools # on Fedora, Red Hat, etc.

另外,您可以使用以下方便的脚本:

$ cat add_cert.sh
certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n $1 -i $1
$ cat list_cert.sh
certutil -d sql:$HOME/.pki/nssdb -L # add '-h all' to see all built-in certs
$ cat download_cert.sh
echo QUIT | openssl s_client -connect $1:443 | sed -ne '/BEGIN CERT/,/END CERT/p'

用法:

add_cert.sh [FILE]
list_cert.sh
download_cert.sh [DOMAIN]

故障排除

  • 使用--auto-ssl-client-auth参数运行 Chrome

    google-chrome --auto-ssl-client-auth

更新 11/2017:此答案可能不适用于大多数较新版本的 Chrome。

更新 02/2016:可在此处找到针对 Mac 用户的更好说明。

  1. 在要添加的站点上,右键单击地址栏中的红色锁定图标: 在此处输入图片说明

    1. 单击标签为 “ 连接”的选项卡,然后单击 “ 证书信息”

    2. 单击详细信息选项卡,然后单击复制到文件...按钮。这将打开 “证书导出向导”,单击 “ 下一步”进入 “ 导出文件格式”屏幕。

    3. 选择DER 编码的二进制 X.509(.CER) ,单击 “ 下一步”。

    4. 单击浏览...,然后将文件保存到计算机。用描述性的名称命名。单击下一步 ,然后单击完成

    5. 打开 Chrome 设置,滚动到底部,然后单击显示高级设置...。

    6. HTTPS / SSL 下 ,单击管理证书...。

    7. 单击 “ 受信任的根证书颁发机构”选项卡,然后单击 “ 导入...”按钮。这将打开 “证书导入向导”。单击 “ 下一步”进入 “ 要导入文件”屏幕。

    8. 单击浏览...,然后选择您之前保存的证书文件,然后单击下一步

    9. 选择将所有证书放入以下存储中 。所选存储应为 “ 受信任的根证书颁发机构” 。如果不是,请单击浏览...,然后选择它。单击下一步完成

    10. 在安全警告上单击 “ ”。

    11. 重新启动 Chrome。

在 Mac 上,您可以通过执行以下操作来创建 Chrome 和 Safari 在系统级别上完全信任的证书:

# create a root authority cert
    ./create_root_cert_and_key.sh

    # create a wildcard cert for mysite.com
    ./create_certificate_for_domain.sh mysite.com

    # or create a cert for www.mysite.com, no wildcards
    ./create_certificate_for_domain.sh www.mysite.com www.mysite.com

上面使用了以下脚本和支持文件v3.ext ,以避免主题备用名称丢失错误

如果要创建一个新的自签名证书,该证书将使用您自己的根权限进行完全信任,则可以使用以下脚本来进行此操作。

create_root_cert_and_key.sh

#!/usr/bin/env bash
    openssl genrsa -out rootCA.key 2048
    openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem

create_certificate_for_domain.sh

#!/usr/bin/env bash

    if [ -z "$1" ]
    then
      echo "Please supply a subdomain to create a certificate for";
      echo "e.g. www.mysite.com"
      exit;
    fi

    if [ ! -f rootCA.pem ]; then
      echo 'Please run "create_root_cert_and_key.sh" first, and try again!'
      exit;
    fi
    if [ ! -f v3.ext ]; then
      echo 'Please download the "v3.ext" file and try again!'
      exit;
    fi

    # Create a new private key if one doesnt exist, or use the xeisting one if it does
    if [ -f device.key ]; then
      KEY_OPT="-key"
    else
      KEY_OPT="-keyout"
    fi

    DOMAIN=$1
    COMMON_NAME=${2:-*.$1}
    SUBJECT="/C=CA/ST=None/L=NB/O=None/CN=$COMMON_NAME"
    NUM_OF_DAYS=825
    openssl req -new -newkey rsa:2048 -sha256 -nodes $KEY_OPT device.key -subj "$SUBJECT" -out device.csr
    cat v3.ext | sed s/%%DOMAIN%%/"$COMMON_NAME"/g > /tmp/__v3.ext
    openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days $NUM_OF_DAYS -sha256 -extfile /tmp/__v3.ext 

    # move output files to final filenames
    mv device.csr "$DOMAIN.csr"
    cp device.crt "$DOMAIN.crt"

    # remove temp file
    rm -f device.crt;

    echo 
    echo "###########################################################################"
    echo Done! 
    echo "###########################################################################"
    echo "To use these files on your server, simply copy both $DOMAIN.csr and"
    echo "device.key to your webserver, and use like so (if Apache, for example)"
    echo 
    echo "    SSLCertificateFile    /path_to_your_files/$DOMAIN.crt"
    echo "    SSLCertificateKeyFile /path_to_your_files/device.key"

v3.ext

authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName = @alt_names

    [alt_names]
    DNS.1 = %%DOMAIN%%

进一步的步骤 - 如何使自签名证书在 Chrome / Safari 中得到完全信任

要使自签名证书在 Chrome 和 Safari 中受到完全信任,您需要将新的证书颁发机构导入 Mac。为此,请遵循以下说明,或在 mitmproxy 网站上对该一般过程进行更详细的说明:

您可以使用以下命令在命令行中通过以下两种方式之一进行操作,该命令将提示您输入密码:

$ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain rootCA.pem

或使用 “ Keychain Access应用程序:

  1. 开放式钥匙串访问
  2. 在 “钥匙串” 列表中选择 “系统”
  3. 在 “类别” 列表中选择 “证书”
  4. 选择 “文件 | 导入项目...”
  5. 浏览到上面创建的文件 “rootCA.pem”,选择它,然后单击 “打开”
  6. 在 “证书” 列表中选择新导入的证书。
  7. 单击 “i” 按钮,或右键单击您的证书,然后选择 “获取信息”
  8. 展开 “信任” 选项
  9. 将 “使用此证书时” 更改为 “始终信任”
  10. 关闭对话框,系统将提示您输入密码。
  11. 关闭并重新打开使用目标域的所有选项卡,它将安全地加载!

另外,如果需要 Java 客户端信任证书,则可以通过将证书导入到 Java 密钥库中来实现。请注意,如果证书已经存在,它将从密钥库中删除该证书,因为它需要在发生更改时进行更新。当然,仅对要导入的证书执行此操作。

import_certs_in_current_folder_into_java_keystore.sh

KEYSTORE="$(/usr/libexec/java_home)/jre/lib/security/cacerts";

function running_as_root()
{
  if [ "$EUID" -ne 0 ]
    then echo "NO"
    exit
  fi

  echo "YES"
}

function import_certs_to_java_keystore
{
  for crt in *.crt; do 
    echo prepping $crt 
    keytool -delete -storepass changeit -alias alias__${crt} -keystore $KEYSTORE;
    keytool -import -file $crt -storepass changeit -noprompt --alias alias__${crt} -keystore $KEYSTORE
    echo 
  done
}

if [ "$(running_as_root)" == "YES" ]
then
  import_certs_to_java_keystore
else
  echo "This script needs to be run as root!"
fi

如果您使用的是 Mac,并且看不到 “导出” 标签或如何获取证书,那么这对我有用:

  1. 单击 https:// 之前的锁
  2. 转到 “连接” 标签
  3. 点击 “证书信息”

    现在您应该看到: 当然,您和您的不同信息应标记为受信任(否则您可能不会在这里)

  4. 将该小证书图标拖到桌面上(或任何位置)。

  5. 双击已下载的. cer 文件,这会将其导入您的钥匙串中,然后打开 “钥匙串访问” 以访问您的证书列表。

    在某些情况下,这就足够了,您现在可以刷新页面。

    除此以外:

  6. 双击新添加的证书。
  7. 在信任下拉列表中,将 “使用此证书时” 选项更改为 “始终信任”

现在重新加载有问题的页面,应该可以解决了!希望这可以帮助。


沃尔夫编辑

为了使此操作更容易一些,您可以使用以下脚本( source ):

  1. 将以下脚本另存为whitelist_ssl_certificate.ssh

    #!/usr/bin/env bash -e
    
    SERVERNAME=$(echo "$1" | sed -E -e 's/https?:\/\///' -e 's/\/.*//')
    echo "$SERVERNAME"
    
    if [[ "$SERVERNAME" =~ .*\..* ]]; then
        echo "Adding certificate for $SERVERNAME"
        echo -n | openssl s_client -connect $SERVERNAME:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | tee /tmp/$SERVERNAME.cert
        sudo security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" /tmp/$SERVERNAME.cert
    else
        echo "Usage: $0 www.site.name"
        echo "http:// and such will be stripped automatically"
    fi
  2. 使脚本可执行(从 shell):

    chmod +x whitelist_ssl_certificate.ssh
  3. 为您想要的域运行脚本(只需复制 / 粘贴完整的 URL 即可):

    ./whitelist_ssl_certificate.ssh https://your_website/whatever

2018 年 4 月 3 日更新

铬团队推荐

https://www.chromium.org/Home/chromium-security/deprecating-powerful-features-on-insecure-origins#TOC-Testing-Powerful-Features

快速超级轻松解决方案

尽管存在安全错误,但可以在错误页面中键入一个秘密的旁路短语以使 Chrome 继续运行: thisisunsafe (在 Chrome 的早期版本中,键入badidea ,甚至在更早版本中, 危险 )。 除非您确实需要它,否则请不要使用它!

资源:

https://chromium.googlesource.com/chromium/src/+/d8fc089b62cd4f8d907acff6fb3f5ff58f168697%5E%21/

(请注意window.atob('dGhpc2lzdW5zYWZl')解析为thisisunsafe

该源的最新版本为 @ https://chromium.googlesource.com/chromium/src/+/refs/heads/master/components/security_interstitials/core/browser/resources/interstitial_large.js ,并且window.atob函数可以在 JS 控制台中执行。

有关 Chrome 小组首次更改旁路词组的原因的背景信息:

https://bugs.chromium.org/p/chromium/issues/detail?id=581189

如果所有其他方法都失败(解决方案 1)

如果 “无论如何继续” 选项不可用,或者旁路词组不起作用,那么一次过就可以使用此技巧:

  1. 通过启用此标志来允许来自localhost的证书错误(注意,Chrome 需要在更改标志值后重新启动):

    chrome://flags/#allow-insecure-localhost

    (以及 @Chris 的投票答案https://stackoverflow.com/a/31900210/430128

  2. 如果您要连接的站点是localhost ,则操作完成。否则,请设置一个 TCP 隧道以本地监听 8090 端口,并连接到端口 443 上的broken-remote-site.com ,确保已安装socat并在终端窗口中运行以下操作:

    socat tcp-listen:8090,reuseaddr,fork tcp:broken-remote-site.com:443

  3. 在浏览器中转到https:// localhost:8090

如果其他所有方法都失败(解决方案 2)

类似于 “如果其他所有方法都失败(解决方案 1)”,在这里我们使用ngrok配置到本地服务的代理。因为您可以通过 TLS(在这种情况下,它由具有有效证书的 ngrok 终止)或通过非 TLS 端点访问 ngrok http 隧道,所以浏览器将不会抱怨证书无效。

下载并安装 ngrok,然后通过ngrok.io公开它:

ngrok http https://localhost

ngrok 将启动并为您提供一个可以连接的主机名,所有请求都将通过隧道传送回本地计算机。