我创建了一个私有根CA并为一些https网站颁发了一些SSL证书,
(我不确定这是否应该被称为自签名证书,在我的例子中,根CA证书是自签名的,但是从根CA颁发的网站的SSL证书不是自签名的。这让我感到困惑如何选择谷歌搜索关键字)。
这些 https 网站在 Chrome、Firefox 中运行良好,但在 Safari 中运行不佳。 (当然,Chrome和Firefox会显示安全警告但给我继续查看的机会,但Safari不会完全如此)。
要点是:我的网站提供了一个证书链文件,它是
The website certificate... +
The root CA certificate...
, Chrome和Firefox可以智能地从证书链文件中找到根CA,但Safari不能。
Safari 报告错误:
Safari 无法打开页面 – Safari 无法打开页面,因为 Safari 无法与服务器“servername”建立安全连接。
当然,我可以提前将根CA证书导入Mac的钥匙串,然后Safari就可以正常工作,甚至不会发出警告。但这不是我想要的,我不能要求用户做这样的手动事情。
如果我生成一个真正的自签名 SSL 证书(没有上层 CA),Safari 将给我一个查看该网站的机会。但这也不是我想要的,因为我有一些调用多个 https 网站的 Java 应用程序,并且不应忽略证书检查,我只想向 Java cacerts keystore 注册一个通用根 CA 证书,以便所有相关的 https 网站都将受到信任自动地。
谁能告诉我如何解决这个问题?我是说无需提前手动导入Root CA,但仍让用户有机会查看网站。请注意,Chrome 和 Firefox 运行良好。
我将指定一些证书扩展来告诉浏览器在哪里找到根 CA 证书,不确定是否还有其他更好的方法。
感叹号:
我的意思不是“只需发送一个新的 CA 证书(在链中或以其他方式)并且您的浏览器“智能”接受它”,我的意思不是让浏览器“接受它”,而是让它通过链验证并询问用户如果他们接受未知根 CA 的风险。
关于“链文件不是CA”:我知道很多,链文件甚至不包含根CA证书,浏览器有一些方法可以找到根CA证书,例如从预装的根CA中,或者可能通过“权威信息访问”证书中的“字段,有一个指向根 CA 的 URL。这是一个不太为人所知的领域,也取决于浏览器的实现:浏览器如何从网站的证书本身获取根CA(我不是指信任或接受)。
我已遵循 Apple 的指南https://support.apple.com/en-us/HT210176
编辑 2021/02/12:Safari 的事情变得越来越有趣:
- https://ip_address 有效。 (当然有安全警告)
- https://dns_name 不起作用(甚至没有安全警告)
- https://dns_name 在隐私浏览模式下工作(当然有安全警告)。
让我附加一些技术细节,这是网站返回的证书链:(请注意,我用诸如 my-host 之类的单词替换了一些敏感名称...)
$ echo Q | openssl s_client -showcerts -verify 5 -connect my-host.my-domain:443
verify depth is 5
CONNECTED(00000005)
depth=1 CN = My Root CA Name
verify error:num=19:self signed certificate in certificate chain
verify return:1
depth=1 CN = My Root CA Name
verify return:1
depth=0 CN = my-host.my-domain
verify return:1
---
Certificate chain
0 s:CN = my-host.my-domain
i:CN = My Root CA Name
-----BEGIN CERTIFICATE-----
MIIDqjCCApKgAwIBAgIJAIh7Dn2n363zMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
BAMMD1RyaWRlbnQgUm9vdCBDQTAeFw0yMTAyMDkwNDU4MzZaFw0yMjAzMTMwNDU4
......
+bnUvHgMmMukXgMLo3e6tnF/Za9z/BCv0KESoFEIg7uWo+IUZv8wXYI8YQEaeeGt
s2et3Js1eBqN1zle8ejoFuInQNS5wkalx0D+zTcCcXVvnUJm2womcKBxFAHJeZDg
vvbsua6FH0JTVjeprdmx1mKkj+MP4N664vP8kAj6
-----END CERTIFICATE-----
1 s:CN = My Root CA Name
i:CN = My Root CA Name
-----BEGIN CERTIFICATE-----
MIIDFzCCAf+gAwIBAgIJAIafS0ZYzGA4MA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
BAMMD1RyaWRlbnQgUm9vdCBDQTAeFw0yMTAyMDkwNDU0MTdaFw0zMTAyMDcwNDU0
......
+b4lJl9fUHd01xqGbBGmp/BL8EI+IveSRTKr/Boi+klqvlgOi5TgUF/0R9gmwPRO
OXIL5hdA7CTsgaURWJ897p5JVYsPtofjnL10
-----END CERTIFICATE-----
---
Server certificate
subject=CN = my-host.my-domain
issuer=CN = My Root CA Name
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2449 bytes and written 432 bytes
Verification error: self signed certificate in certificate chain
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: F6FF34026A5B10EE149D442FA4035916330AE09AC2B771369EA0B94754501892
Session-ID-ctx:
Master-Key: BF444224C15CEDC3309F01E4C5DE8F8331AF9B82F0613601FE5D1B677F6526DD3FF97BB00DB3DC5BB0E35EA489861FF6
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - d6 5f 48 e0 90 10 48 22-46 83 7f 82 d1 a4 17 da ._H...H"F.......
0010 - 17 10 e8 1e e1 dc 17 58-9c 36 e8 d1 36 f5 d7 f6 .......X.6..6...
......
00d0 - 85 63 2a 3c 0e 6c 18 f3-27 fb 21 7d bd 3d 8b 33 .c*<.l..'.!}.=.3
00e0 - bf 3c 60 da 06 2e 23 3b-a0 f2 f6 88 5e 0c 2b f2 .<`...#;....^.+.
Start Time: 1612937133
Timeout : 7200 (sec)
Verify return code: 19 (self signed certificate in certificate chain)
Extended master secret: yes
---
DONE
apache2(2.4.29 Ubuntu) 配置:
<IfModule mod_ssl.c>
<VirtualHost *:443>
SSLEngine On
SSLCertificateFile /etc/apache2/certs/web_cert.pem
SSLCertificateKeyFile /etc/apache2/certs/web_key.pem
DocumentRoot /var/www
LimitRequestFieldSize 32768
</VirtualHost>
</IfModule>
请注意,/etc/apache2/certs/web_cert.pem实际上是网站证书和根CA证书的串联,即证书链文件。
其他信息:
根CA证书:
# openssl x509 -text -noout < /etc/apache2/certs/root_ca_cert.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
86:9f:4b:46:58:cc:60:38
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = My Root CA Name
Validity
Not Before: Feb 9 04:54:17 2021 GMT
Not After : Feb 7 04:54:17 2031 GMT
Subject: CN = My Root CA Name
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
......
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
EE:BF:15:0D:35:BC:4C:92:88:4F:9B:21:FC:B6:C4:29:C4:35:9E:D3
X509v3 Authority Key Identifier:
keyid:EE:BF:15:0D:35:BC:4C:92:88:4F:9B:21:FC:B6:C4:29:C4:35:9E:D3
X509v3 Key Usage:
Certificate Sign, CRL Sign
Signature Algorithm: sha256WithRSAEncryption
......
根 CA 密钥
# openssl rsa -text -noout < /etc/apache2/certs/root_ca_key.pem
Private-Key: (2048 bit)
modulus:
......
publicExponent: 65537 (0x10001)
privateExponent:
......
prime1:
......
prime2:
......
exponent1:
......
exponent2:
......
coefficient:
......
网站证书:
# openssl x509 -text -noout < /etc/apache2/certs/web_cert.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
88:7b:0e:7d:a7:df:ad:f3
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = My Root CA Name
Validity
Not Before: Feb 9 04:58:36 2021 GMT
Not After : Mar 13 04:58:36 2022 GMT
Subject: CN = my-host.my-domain
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
......
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
E2:83:31:54:D3:49:D1:5E:78:6C:29:84:15:C9:80:48:26:AF:7A:EF
X509v3 Authority Key Identifier:
keyid:EE:BF:15:0D:35:BC:4C:92:88:4F:9B:21:FC:B6:C4:29:C4:35:9E:D3
DirName:/CN=My Root CA Name
serial:86:9F:4B:46:58:CC:60:38
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage: critical
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:my-host.my-domain, IP Address:100.100.100.100
Signature Algorithm: sha256WithRSAEncryption
......
网站的证书密钥:
# openssl rsa -text -noout < /etc/apache2/certs/web_key.pem
Private-Key: (2048 bit)
modulus:
......
publicExponent: 65537 (0x10001)
privateExponent:
......
prime1:
......
prime2:
......
exponent1:
......
exponent2:
......
coefficient:
......
钥匙串验证结果:
s# openssl verify -CAfile /etc/apache2/certs/root_ca_cert.pem < /etc/apache2/certs/web_cert.pem
stdin: OK
答案1
抱歉打扰大家了,不确定是哪个部分最终使它起作用,在清除 HSTS plist 和浏览器历史记录并重新启动后,现在它可以起作用了。我还确认两个具有相同 MacOS 版本的用户可以正常工作,只有我的 Macbook 和另一位同事的 Macbook 出现问题。接缝是因为我们手动注册了其他具有相同名称的根 CA。
摘要:当问题发生时,通过 IP 的 https 可以工作,隐私浏览模式对 dnsname 和 ip 都有效,并且某些用户可以工作,现在我的也可以工作,当然,都显示安全警告,我认为问题不是因为“Apple有意识地决定,如果存在正在使用的 CA 证书并且不在您的信任存储中,则不提供此选项”,但由于浏览器缓存或 HSTS 设置等原因,毕竟是一些本地问题。