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

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


当前回答

Linux系统

如果您使用的是Linux,也可以关注以下官方wiki页面:

在Linux上配置SSL证书。NSS共享数据库和LINUXNSS共享数据库如何

基本上:

单击带有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工具。

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

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客户端身份验证参数运行Chromegoogle chrome--自动ssl客户端身份验证

其他回答

下面是一个仅使用Java 8 keytool.exe而不是openssl的解决方案:

@echo off
set PWD=changeit
set DNSNAME=%COMPUTERNAME%

echo create ca key
keytool -genkeypair -alias ca -keystore test.jks -keyalg RSA -validity 3650 -ext bc:critical=ca:true -dname "CN=CA" -storepass:env PWD -keypass:env PWD
echo generate cert request for ca signing
keytool -certreq -keystore test.jks -storepass:env PWD -alias ca -file ca.csr -ext bc:critical=ca:true
echo generate signed cert
keytool -gencert -keystore test.jks -storepass:env PWD -alias ca -infile ca.csr -outfile ca.cer -validity 3650 -ext bc:critical=ca:true
echo CA created. Import ca.cer in windows and firefox' certificate store as "Trusted CA".
pause

echo create server cert key for %DNSNAME%
keytool -genkeypair -alias leaf -keystore test.jks -keyalg RSA -validity 3650 -ext bc=ca:false -ext san=dns:%DNSNAME%,dns:localhost,ip:127.0.0.1 -dname "CN=Leaf" -storepass:env PWD -keypass:env PWD
echo generate cert request
keytool -certreq -keystore test.jks -storepass:env PWD -alias leaf -file leaf.csr -ext bc=ca:false -ext san=dns:%DNSNAME%,dns:localhost,ip:127.0.0.1
echo generate signed cert
keytool -gencert -keystore test.jks -storepass:env PWD -alias ca -infile leaf.csr -outfile leaf.cer -validity 3650 -ext bc=ca:false -ext san=dns:%DNSNAME%,dns:localhost,ip:127.0.0.1

rem see content
rem keytool -printcert -file leaf.cer -storepass:env PWD 

echo install in orig keystore
keytool -importcert -keystore test.jks -storepass:env PWD -file leaf.cer -alias leaf

echo content of test.jks:
keytool -list -v -storepass:env PWD -keystore test.jks
pause

您也可以使用管道而不是文件,但是使用这些文件,如果出现问题,您可以检查中间结果。SSL在windows上通过IE11、Edge、FF54、Chrome60和Android上的Chrome60进行了测试。

请在使用脚本之前更改默认密码。

Chrome 58+更新(发布于2017-04-19)

从Chrome 58开始,仅使用commonName识别主机的功能被删除。证书现在必须使用subjectAltName来标识其主机。请参阅此处的进一步讨论和此处的bug跟踪器。在过去,subjectAltName仅用于多主机证书,因此一些内部CA工具不包括这些证书。

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

因此,无论您使用什么方法来生成自签名证书(或由自签名CA签名的证书),请确保服务器的证书包含具有正确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下的“安全”选项卡)中,您应该看到它列在“扩展名”下作为证书主题替代名称:

我成功地遵循了凯伦的回答,并得到了托比·J的重要更新,但我不得不做出修改:

创建自签名证书时,必须将新的subjectAltName字段放在v3_ca扩展下,而不是v3_req。我将/etc/ssl/openssl.conf复制到一个临时文件中,然后在[v3_ca]下添加了一行subjectAltName=DNS:*.example.com。然后将该文件传递给cert创建命令,类似于

  openssl req -x509 -nodes -newkey rsa:2048 \
          -config /tmp/openssl-revised.cfg \
          -keyout example.com.key -out example.com.crt

并遵循kellen更新的步骤。

正如有人指出的,你需要重启所有的Chrome,而不仅仅是浏览器窗口。最快的方法是打开一个选项卡。。。

chrome://restart

WINDOWS 2017年6月WINDOWS Server 2012

我听从了布拉德·帕克斯的回答。在Windows上,您应该在受信任的根证书颁发机构存储中导入rootCA.pem。

我执行了以下步骤:

openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -newkey rsa:4096 -sha256 -days 1024 -out rootCA.pem
openssl req -new -newkey rsa:4096 -sha256 -nodes -keyout device.key -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 2000 -sha256 -extfile v3.ext

其中v3.ext为:

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

[alt_names]
DNS.1 = localhost
IP.1 = 192.168.0.2
IP.2 = 127.0.0.1

然后,在我的例子中,我有一个自托管的web应用程序,所以我需要将证书与IP地址和端口绑定,证书应该在我的存储库中,并带有私钥信息,所以我导出为pfx格式。

openssl pkcs12 -export -out device.pfx -inkey device.key -in device.crt

使用mmc控制台(文件/添加或删除管理单元/证书/添加/计算机帐户/本地计算机/确定),我在个人存储中导入了pfx文件。

后来我使用这个命令绑定证书(您也可以使用HttpConfig工具):

netsh http add sslcert ipport=0.0.0.0:12345 certhash=b02de34cfe609bf14efd5c2b9be72a6cb6d6fe54 appid={BAD76723-BF4D-497F-A8FE-F0E28D3052F4}

certhash=证书Thumprint

appid=GUID(您的选择)

首先,我尝试以不同的方式在受信任的根证书颁发机构上导入证书“device.crt”,但仍然收到相同的错误:

但我意识到我应该导入根权限的证书,而不是域的证书。所以我使用mmc控制台(文件/添加或删除管理单元/证书/添加/计算机帐户/本地计算机/OK),在受信任的根证书颁发机构存储中导入了rootCA.pem。

重新启动Chrome,它就可以工作了。

使用localhost:

或IP地址:

我唯一做不到的是,它有过时的密码(图片上的红色方框)。在这一点上,我们非常感谢帮助。

使用makecert,无法添加SAN信息。使用NewSelfSignedCertificate(Powershell),您可以添加SAN信息,它也可以工作。