为域名和子域名创建自签名证书 - NET::ERR_CERT_COMMON_NAME_INVALID

98

我按照这篇教程为了开发目的在Windows上创建签名的SSL证书,对于我的一个域名它很有效(我使用hosts文件模拟DNS)。然后我意识到我有许多子域名,为每个子域名创建证书会非常麻烦。因此,我尝试使用通配符在Common字段中创建证书,就像serverfault上的一些回答建议的那样。就像这样:

Common Name: *.myserver.net/CN=myserver.net

然而,将证书导入到受信任的根证书颁发机构后,在Chrome中出现了NET::ERR_CERT_COMMON_NAME_INVALID错误,对于主域和其所有子域名,例如:https://sub1.myserver.nethttps://myserver.net

该服务器无法证明它是myserver.net;它的安全证书来自*.myserver.net/CN=myserver.net。

这可能是由于配置错误或攻击者拦截您的连接引起的。

是否在通用名称字段中有错误导致此错误?


我花了很多时间来修复这个问题。请查看我的答案,链接在这里:https://dev59.com/jlgQ5IYBdhLWcg3wZDKd#49150891 - Alex Vasilev
9个回答

64

2
这个指南帮助我在Mac OSX上创建了自签名证书:https://alexanderzeitler.com/articles/Fixing-Chrome-missing_subjectAltName-selfsigned-cert-openssl/ - carlosvini
1
尽管错误信息没有提到主题备用名称,但这解决了我的问题。谢谢! - Sharpiro
最初,对我来说使用SAN获取证书也很麻烦。这里发布的一些答案可能也会有所帮助:https://dev59.com/E77pa4cB1Zd3GeqPyWwQ#74802552 - JonathanDavidArndt

29

解决办法是将您使用的域名添加为“subjectAltName”(X509v3主题备用名称)。这可以通过更改您的OpenSSL配置(在Linux上为/etc/ssl/openssl.cnf)并修改v3_req部分来完成,使其如下所示:

[ v3_req ]

# Extensions to add to a certificate request

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = myserver.net
DNS.2 = sub1.myserver.net

在这种情况下,不要忘记在生成新证书时使用-extensions v3_req开关。(另请参见如何使用OpenSSL生成带有SubjectAltName的自签名证书?)


2
使用 subjectAltName = @alt_names 完全解决了我的问题。我之前通过提供 CN=*.example.com 将 DNS 身份绑定到了我的域名上。设置 DNS.1 = example.comDNS.2 = *.example.com 就解决了问题。奇怪的是(对我来说),这一切都在 2017-03-17 之前都能正常工作,但在一天之后就停止了(当时运行了大量的 Windows 更新)。然而,在 Linux 上没有任何问题,这只出现在 WindowsChromeFirefox 上。 - bossi
@bossi:不幸的是,我在Chrome/Ubuntu上遇到了这个问题。证书也不复杂,单个主机,单个DN(内部GitLab存储库)。 - Pawel Kraszewski
2
@bossi 我打赌你的Windows版本是测试版,对吧?Chrome已经弃用了没有subjectAltName的证书自Chrome 58起,目前正在测试中。这让我很困扰,因为我不仅没有看到任何关于它的东西,而且错误名称非常误导人(无效的不是通用名称!)我和你相反;这只发生在我的Linux上,所以我花了几个小时来修复我的本地证书存储。 - Tobias J
2
@TobyJ,这是58.0.3029.19 beta (64-bit)版本。我已经使用正确的subjectAltName重新生成了证书树,现在一切都正常了。我同意,错误信息非常误导人,因为无效的不是CommonName。如果消息显示“证书缺少适当的subjectAltName”,那么每个人都会更加满意。 - Pawel Kraszewski
@PawelKraszewski 现在(v59),当您在错误页面上单击“高级”时,您可以阅读有关它的更多信息,并且有:不正确的subjectAltName - TheFrost
显示剩余6条评论

25

创建openssl.conf文件:

[req]
default_bits = 2048
default_keyfile = oats.key
encrypt_key = no
utf8 = yes
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no

[req_distinguished_name]
C = US
ST = Cary
L = Cary
O  = BigCompany
CN = *.myserver.net

[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1 = myserver.net
DNS.2 = *.myserver.net
运行此命令:

Run this command:

openssl req -x509 -sha256 -nodes -days 3650 -newkey rsa:2048 -keyout app.key -out app.crt  -config openssl.conf

输出文件app.crtapp.key适用于我。


2
DNS.1 = *.myserver.net 中有一个打字错误。应该是 DNS.2 = *.myserver.net。对我来说完全没问题。 - Artem Stepin
3
如果你正在使用Windows操作系统,可以通过在管理员权限下运行的命令提示符并使用以下位置安装了Git的OpenSSL来完成此操作:"C:\Program Files\Git\usr\bin\openssl.exe" req -x509 -sha256 -nodes -days 3650 -newkey rsa:2048 -keyout app.key -out app.crt -config openssl.conf。 - George
我写了CN = localhost,DNS.1 = localhost,DNS.2 = *.localhost:8080,但它对我不起作用。我还需要改变什么吗? - Esqarrouth
2
我一直无法让它正常工作(Chrome仍然显示证书不受信任)。我想知道为什么它会说“default_keyfile = oats.key”。 - Ryan

24

正如Rahul所说,这是一个常见的Chrome和OSX的bug。过去我也遇到了类似的问题。事实上,当我测试本地网站时,我终于厌倦了额外点击两次(是的,我知道这不是很多)的操作。

至于解决这个问题的可能方法[使用Windows],我建议使用众多自签名证书工具之一

推荐步骤:

  1. 创建自签名证书
  2. 将证书导入Windows证书管理器
  3. 在Chrome证书管理器中导入证书
    注意:第3步将解决经历一次后Google解决该漏洞的问题......考虑到时间已经很久远,未来也没有预计的时间表。**

    尽管我更喜欢在开发时使用Chrome,但最近我发现自己更多地在使用Firefox开发者版,它没有这个问题。

    希望这可以帮到你:)

你链接的错误 A) 只适用于 OS X,并且 B) 涉及带有尾随“。”的域,这两者都不适用于 @Zed。 - Philip
哦,那应该是哪个链接呢? - Thomas.Donnelly
Chromium bug(98627)的链接 - Philip
无论如何,我提出的修复方法在Windows上也可以使用,因为我已经使用过很多次。 - Thomas.Donnelly
尽管我更喜欢使用Chrome进行开发,但最近我发现自己在使用Firefox Developer Edition,它没有这个问题。在这一点上完全赞同。 - Ash

15

您的通配符*.example.com并未覆盖根域名example.com,但将覆盖任何子域名变体,例如www.example.comtest.example.com

首选方法是建立主题备用名称(Subject Alternative Names),就像Fabian's Answer所示,但请记住,Chrome当前要求公共名称(Common Name)必须另外列为其中一个主题备用名称(正如在其答案中正确展示的那样)。我最近发现了这个问题,因为我拥有公共名称example.com和SANswww.example.comtest.example.com,但在Chrome中收到了NET::ERR_CERT_COMMON_NAME_INVALID警告。我不得不生成一个新的证书签名请求,其中example.com既是公共名称,也是其中一个SAN。然后Chrome完全信任该证书。别忘了将根证书导入到Chrome中,以作为识别网站的可信机构。


如果有人正在使用 Pantheon 进行托管,他们似乎会在你将证书上传到他们的平台时重新构建与其关联的通用名称,从而导致此问题。您必须针对他们提供的自定义静态 IP 进行测试,以查看证书的通用名称是否在设置过程中保持完好。 - serraosays
1
太棒了!“您的通配符*.example.com不包括根域example.com,但将覆盖子域上的任何变体,例如www.example.com或test.example.com。”这正是我遇到的问题。解决方法很简单,只需在`openssl.cnf`的`[alt_names]`下包括`DNS.1 = example.comDNS.2 = *.example.com`即可。 - Ben Johnson

5

我认为这可能是chrome的一个bug。很久以前就出现了类似的问题: 见此链接。

尝试在不同的浏览器中试试。我想它应该能正常工作。


1
如果你厌倦了这个错误。你可以让Chrome不再出现这种情况。我并不是说这是最好的方法,只是说这是一种方法。
作为一种解决方法,可以创建一个Windows注册表键来允许Google Chrome使用服务器证书的commonName匹配主机名,如果该证书缺少subjectAlternativeName扩展名,并且成功验证并链到本地安装的CA证书。数据类型:布尔值[Windows:REG_DWORD] Windows注册表位置:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome Windows/Mac/Linux/Android首选项名称:EnableCommonNameFallbackForLocalAnchors值:0x00000001(Windows),true(Linux),true(Android)(Mac)。要创建Windows注册表键,请按照以下步骤操作:打开记事本,将以下内容复制并粘贴到记事本中, Windows Registry Editor Version 5.00[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]“EnableCommonNameFallbackForLocalAnchors”=dword:00000001,然后单击“文件”>“另存为”,文件名:任何文件名.reg,保存类型:所有文件。选择文件的首选位置,单击“保存”。双击保存的文件运行它,在注册表编辑器警告上单击“是”。
我可以为您翻译中文。这段内容是关于Symantec支持页面的信息: https://support.symantec.com/en_US/article.TECH240507.html

它不再起作用了。但感谢提供信息。第一个答案(从页面顶部看)表明问题出在主题备用名称上。 - Bogdan Mart

1
对于遇到此问题并希望冒险测试的所有人,有一个解决方案:在Chrome中进入无痕模式,您将能够打开“高级”并单击“前往某个网址”。
如果您需要检查一些自己维护并作为开发人员进行测试的网站(而且当您尚未配置适当的开发证书时),这可能会有所帮助。
当然,这不适用于在生产中使用网站的人,其中此错误指示网站安全存在问题。

1
提供的解决方案对我来说不起作用(在Chrome或Firefox中),当我创建本地开发和测试的PWA时。请勿用于生产!我能够使用以下方法:
  1. 在线证书工具网站,提供以下选项:
    • 通用名称:添加“localhost”和您系统的IP地址,例如192.168.1.12
    • 主题备用名称:添加“DNS”=“localhost”和“IP”=<your ip here, e.g. 192.168.1.12>
    • “CRS”下拉选项设置为“自签名”
    • 所有其他选项均为默认设置
  2. 下载所有链接
  3. 通过双击并选择“安装”将.p7b证书导入Windows/OSX?/Linux?
  4. 将证书添加到节点应用程序中...使用Google的PWA示例
    • 在server.js文件顶部添加const https = require('https'); const fs = require('fs');
    • 在server.js文件底部注释掉return app.listen(PORT, () => { ... });
    • 在下面添加https.createServer({ key: fs.readFileSync('./cert.key','utf8'), cert: fs.readFileSync('./cert.crt','utf8'), requestCert: false, rejectUnauthorized: false }, app).listen(PORT)

我在Chrome或Firefox中没有更多的错误了


这在我的Angular应用程序中有效。谢谢James。 - Timathon

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