我已经为localhostCN创建了一个自签名的SSL证书。正如预期的那样,Firefox在最初抱怨后接受了这个证书。然而,Chrome和IE拒绝接受它,即使在将证书添加到Trusted Roots下的系统证书存储之后。尽管当我在Chrome的HTTPS弹出窗口中单击“查看证书信息”时,证书被列为正确安装,但它仍然坚称证书不可信。

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


当前回答

我自己解决了这个问题,没有更改任何具有适当SSL证书的浏览器上的设置。我使用的是mac,所以需要对我的ssl证书进行密钥链更新。我不得不在ssl认证中添加主题alt名称,以便chrome接受它

我的示例很容易使用命令和配置文件:

添加这些文件,这个示例都在一个根目录中

ssl.conf文件

[ req ]
default_bits       = 4096
distinguished_name = req_distinguished_name
req_extensions     = req_ext

[ req_distinguished_name ]
countryName                 = Country Name (2 letter code)
stateOrProvinceName         = State or Province Name (full name)
localityName                = Locality Name (eg, city)
organizationName            = Organization Name (eg, company)
commonName                  = Common Name (e.g. server FQDN or YOUR name)
commonName_max              = 64

[ req_ext ]
subjectAltName = @alt_names

[alt_names]
DNS.1   = localhost

运行命令以创建证书:

openssl req -newkey rsa:4096 -nodes -keyout key.pem -x509 -days 3650 -out certificate.pem -extensions req_ext -config ssl.conf -subj '/CN=localhost/O=Stackflow/C=US/L=Los Angeles/OU=StackflowTech'

对于仅添加可信证书的Mac(必需):

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

对于windows,您必须找到如何在本地独立验证我们的ssl证书。我不使用Windows。对不起,窗户的男男女女。

我使用的是带有express.js的node.js服务器,只需要我的密钥和证书,如下所示:

应用程序.js

const https = require('https');
const Express = require('express');
const fs = require('fs');
const app = new Express();
const server = https.createServer({
    key: fs.readFileSync('./key.pem'),
    cert: fs.readFileSync('./certificate.pem'),
}, app);
server.listen(3000);

我可能会在将来为其他后端框架执行此操作,因此我可以在将来为其它框架更新此示例。但这是我在Node.js中解决的问题。清除浏览器缓存并在https上运行应用程序://

下面是一个跑步的例子https://localhost在Mac用户的Node.js服务器上:

https://github.com/laynefaler/Stack-Overflow-running-HTTPS-localhost

快乐编码!

其他回答

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

您应该使用以下项创建PKI:;

自签名根CA。子/中间证书[由根CA签署]。正常/最终实体证书[由根CA或子CA签名]commonName或subjectAltName(SAN)作为“localhost”。还包括https://localhost/作为SAN中的URI。将该根CA作为“受信任的根证书颁发机构”导入/安装到Windows操作系统中。因为你提到了IE:Google Chrome在寻找证书链时使用了相同的资源。将该最终实体证书安装为您的web服务器证书,它将停止抱怨该错误消息。

希望这有帮助。

在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,以避免主题替代名称丢失错误

如果您想使用自己的根权限创建一个完全受信任的新的自签名证书,可以使用这些脚本。

创建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

为域.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应用程序:

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

另外,如果您需要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

更新日期:2020年4月23日

铬团队推荐

https://www.chromium.org/Home/chromium-security/deprecating-powerful-features-on-insecure-origins#TOC-测试强大功能

快速超级简单解决方案

有一个秘密的绕过短语,可以在错误页面中输入,让Chrome不顾安全错误继续运行:这是不安全的(在早期版本的Chrome中,键入baddidea,甚至更早版本的危险)。除非你完全明白为什么需要它,否则不要使用它!

资料来源:

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

(注意,window.atob('dGhpc2lzdW5zYWZl')解析为此isnsafe)

源的最新版本为@https://chromium.googlesource.com/chromium/src/+/refs/heads/master/components/security_interentials/corebrowser/resources/intertial_large.js和window.atob函数可以在js控制台中执行。

有关Chrome团队为何更改旁路短语(第一次)的背景信息:

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

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

对于快速一次性,如果“无论如何继续”选项不可用,或者旁路短语也不起作用,这个黑客很好:

通过启用此标志,允许来自本地主机的证书错误(注意,更改标志值后,Chrome需要重新启动):chrome://flags/#allow-不安全的本地主机(并投票赞成答案https://stackoverflow.com/a/31900210/430128作者@Chris)如果要连接的站点是localhost,那么就完成了。否则,设置TCP隧道以在本地侦听端口8090,并连接到端口443上的broken-remote-site.com,确保已安装socat并在终端窗口中运行以下内容:socat tcp侦听:8090,reuseddr,fork tcp:断开远程站点.com:443去https://localhost:8090在浏览器中。

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

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

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

ngrok http https://localhost

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

我刚刚在我的chrome中启用了允许不安全的localhost标志,就这样。

步骤。

类型chrome://flags在您的铬标签中。搜索允许不安全的本地主机标志并启用它。重新启动chrome浏览器。

现在,您将不会看到不安全的警告https://localhost地点。

在受信任的根CA存储中添加CA证书。转到chrome并启用此标志!

chrome://flags/#allow-不安全的本地主机

最后,只需使用*.me域或任何有效的域,如*.com和*.net,并将它们保存在主机文件中。对于我的本地设备,我使用*.me或*.com,主机文件维护如下:

添加到主机。C: /windows/system32/drivers/etc/hosts127.0.0.1下一页

注意:如果在执行此操作时浏览器已打开,则错误将继续显示。因此,请关闭浏览器并重新启动。更好的办法是,隐姓埋名,或者立即开始新的疗程。