Google 是否为不同的客户端返回不同的证书?
Is Google returning different certificates for different clients?
class 我正在查看 google.com
的 TLS 证书链。当我在 Chrome 或 Firefox 浏览器中单击时,根证书显示为 GTS Root R1
,有效期可达 2036,自签名,因此它必须是根证书。
但是,如果我使用以下代码在 Python 中检查相同内容,我会得到一个有效期为 2028 年的 GTS Root R1
证书,由 GlobalSign nv-sa
签名,所以这个该不是根证书了!
是否有可能 Google.com returns 两个不同的证书链,具体取决于哪个客户端发出请求?如果它假设客户端接受 GTS Root R1
作为根证书,它 returns 这个,否则它 returns 一个由 GlobalSign nv-sa
?
签名的
如果是,为什么?
以下是带有证书及其 digest/sha256 的链。现在,当我在浏览器中查看证书链时,前两个具有相同的 digest
/ sha-256
,但第三个具有不同的 digest
。所以我绝对认为我会根据客户获得不同的链...
Certificate #0
Subject b'CN': b'*.google.com'
notBefore: b'20211101021952Z'
notAfter: b'20220124021951Z'
version:2
sigAlg: b'sha256WithRSAEncryption'
digest: b'E9:7C:86:18:34:DE:F4:11:4D:2D:5E:6F:1A:49:22:A1:04:EE:9E:7C:8D:CB:72:3F:6D:67:58:8F:7E:F3:4B:AB'
issuer: <X509Name object '/C=US/O=Google Trust Services LLC/CN=GTS CA 1C3'>
Certificate #1
Subject b'C': b'US'
Subject b'O': b'Google Trust Services LLC'
Subject b'CN': b'GTS CA 1C3'
notBefore: b'20200813000042Z'
notAfter: b'20270930000042Z'
version:2
sigAlg: b'sha256WithRSAEncryption'
digest: b'23:EC:B0:3E:EC:17:33:8C:4E:33:A6:B4:8A:41:DC:3C:DA:12:28:1B:BC:3F:F8:13:C0:58:9D:6C:C2:38:75:22'
issuer: <X509Name object '/C=US/O=Google Trust Services LLC/CN=GTS Root R1'>
Certificate #2
Subject b'C': b'US'
Subject b'O': b'Google Trust Services LLC'
Subject b'CN': b'GTS Root R1'
notBefore: b'20200619000042Z'
notAfter: b'20280128000042Z'
version:2
sigAlg: b'sha256WithRSAEncryption'
digest: b'3E:E0:27:8D:F7:1F:A3:C1:25:C4:CD:48:7F:01:D7:74:69:4E:6F:C5:7E:0C:D9:4C:24:EF:D7:69:13:39:18:E5'
issuer: <X509Name object '/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA'>
我用来获取证书的python代码:
from OpenSSL import SSL, crypto
import socket, certifi
def dump_cert(cert):
for component in cert.get_subject().get_components():
print("Subject %s: %s" % (component))
print("notBefore:", cert.get_notBefore())
print("notAfter:", cert.get_notAfter())
print("version:" + str(cert.get_version()))
print("sigAlg:", cert.get_signature_algorithm())
print("digest:", cert.digest('sha256'))
print("issuer:", cert.get_issuer())
print()
def get_connection_chain(host, port = 443):
dst = (str.encode(host), port)
ctx = SSL.Context(SSL.TLSv1_2_METHOD)
s = socket.create_connection(dst)
s = SSL.Connection(ctx, s)
s.set_connect_state()
s.set_tlsext_host_name(dst[0])
s.sendall(b'HEAD / HTTP/1.2\n\n')
s.recv(16)
return (s, s.get_peer_cert_chain())
def dump_chain(chain):
for pos, cert in enumerate(chain):
print("Certificate #" + str(pos))
dump_cert(cert)
conn, chain = get_connection_chain("google.ch")
dump_chain(chain)
所以感谢 President James K. Polk
我想我更好地理解发生了什么:
- 根据 https://pki.goog/repository/,有两个版本的
GTS Root R1
证书具有相同的 public 密钥:
- 根证书
GTS Root R1
- 中间证书
GTS Root R1 Cross
,由 GlobalSign nv-sa
签名,是根证书。
因此浏览器收到问题中给出的证书链。然后从证书链的叶节点开始,也就是Certificate #0
。浏览器通过其存储的根证书列表来验证叶证书。如果找不到,它会转到下一个条目,Certificate #1
.
在google.com的例子中,它发现它有Certificate #1
的根证书并使用这个,忽略Certificate #2
。尽管我不太确定为什么这样做:
- 是否希望在某个时候摆脱
GlobalSign
证书?
- 是为了冗余吗?如果一个证书被吊销,另一个证书仍然有效?
描述此内容的博客条目如下:https://scotthelme.co.uk/cross-signing-alternate-trust-paths-how-they-work/
class 我正在查看 google.com
的 TLS 证书链。当我在 Chrome 或 Firefox 浏览器中单击时,根证书显示为 GTS Root R1
,有效期可达 2036,自签名,因此它必须是根证书。
但是,如果我使用以下代码在 Python 中检查相同内容,我会得到一个有效期为 2028 年的 GTS Root R1
证书,由 GlobalSign nv-sa
签名,所以这个该不是根证书了!
是否有可能 Google.com returns 两个不同的证书链,具体取决于哪个客户端发出请求?如果它假设客户端接受 GTS Root R1
作为根证书,它 returns 这个,否则它 returns 一个由 GlobalSign nv-sa
?
如果是,为什么?
以下是带有证书及其 digest/sha256 的链。现在,当我在浏览器中查看证书链时,前两个具有相同的 digest
/ sha-256
,但第三个具有不同的 digest
。所以我绝对认为我会根据客户获得不同的链...
Certificate #0
Subject b'CN': b'*.google.com'
notBefore: b'20211101021952Z'
notAfter: b'20220124021951Z'
version:2
sigAlg: b'sha256WithRSAEncryption'
digest: b'E9:7C:86:18:34:DE:F4:11:4D:2D:5E:6F:1A:49:22:A1:04:EE:9E:7C:8D:CB:72:3F:6D:67:58:8F:7E:F3:4B:AB'
issuer: <X509Name object '/C=US/O=Google Trust Services LLC/CN=GTS CA 1C3'>
Certificate #1
Subject b'C': b'US'
Subject b'O': b'Google Trust Services LLC'
Subject b'CN': b'GTS CA 1C3'
notBefore: b'20200813000042Z'
notAfter: b'20270930000042Z'
version:2
sigAlg: b'sha256WithRSAEncryption'
digest: b'23:EC:B0:3E:EC:17:33:8C:4E:33:A6:B4:8A:41:DC:3C:DA:12:28:1B:BC:3F:F8:13:C0:58:9D:6C:C2:38:75:22'
issuer: <X509Name object '/C=US/O=Google Trust Services LLC/CN=GTS Root R1'>
Certificate #2
Subject b'C': b'US'
Subject b'O': b'Google Trust Services LLC'
Subject b'CN': b'GTS Root R1'
notBefore: b'20200619000042Z'
notAfter: b'20280128000042Z'
version:2
sigAlg: b'sha256WithRSAEncryption'
digest: b'3E:E0:27:8D:F7:1F:A3:C1:25:C4:CD:48:7F:01:D7:74:69:4E:6F:C5:7E:0C:D9:4C:24:EF:D7:69:13:39:18:E5'
issuer: <X509Name object '/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA'>
我用来获取证书的python代码:
from OpenSSL import SSL, crypto
import socket, certifi
def dump_cert(cert):
for component in cert.get_subject().get_components():
print("Subject %s: %s" % (component))
print("notBefore:", cert.get_notBefore())
print("notAfter:", cert.get_notAfter())
print("version:" + str(cert.get_version()))
print("sigAlg:", cert.get_signature_algorithm())
print("digest:", cert.digest('sha256'))
print("issuer:", cert.get_issuer())
print()
def get_connection_chain(host, port = 443):
dst = (str.encode(host), port)
ctx = SSL.Context(SSL.TLSv1_2_METHOD)
s = socket.create_connection(dst)
s = SSL.Connection(ctx, s)
s.set_connect_state()
s.set_tlsext_host_name(dst[0])
s.sendall(b'HEAD / HTTP/1.2\n\n')
s.recv(16)
return (s, s.get_peer_cert_chain())
def dump_chain(chain):
for pos, cert in enumerate(chain):
print("Certificate #" + str(pos))
dump_cert(cert)
conn, chain = get_connection_chain("google.ch")
dump_chain(chain)
所以感谢 President James K. Polk
我想我更好地理解发生了什么:
- 根据 https://pki.goog/repository/,有两个版本的
GTS Root R1
证书具有相同的 public 密钥:- 根证书
GTS Root R1
- 中间证书
GTS Root R1 Cross
,由GlobalSign nv-sa
签名,是根证书。
- 根证书
因此浏览器收到问题中给出的证书链。然后从证书链的叶节点开始,也就是Certificate #0
。浏览器通过其存储的根证书列表来验证叶证书。如果找不到,它会转到下一个条目,Certificate #1
.
在google.com的例子中,它发现它有Certificate #1
的根证书并使用这个,忽略Certificate #2
。尽管我不太确定为什么这样做:
- 是否希望在某个时候摆脱
GlobalSign
证书? - 是为了冗余吗?如果一个证书被吊销,另一个证书仍然有效?
描述此内容的博客条目如下:https://scotthelme.co.uk/cross-signing-alternate-trust-paths-how-they-work/