简体   繁体   English

谷歌是否为不同的客户返回不同的证书?

[英]Is Google returning different certificates for different clientts?

for a class I'm looking at the TLS certificate chain for google.com .对于 class 我正在查看google.com的 TLS 证书链。 When I click in the Chrome or Firefox browser, the root certificate is shown as GTS Root R1 with a validity up to 2036, self-signed, so it must be a root-certificate.当我在 Chrome 或 Firefox 浏览器中单击时,根证书显示为GTS Root R1 ,有效期为 2036,自签名,因此它必须是根证书。

However, if I check the same in Python using the following code, I get a GTS Root R1 certificate with a validity of 2028, which is signed by GlobalSign nv-sa , so this time it's NOT a root-certificate!但是,如果我使用以下代码在 Python 中检查相同的内容,我将获得有效期为 2028 的GTS Root R1证书,该证书由GlobalSign nv-sa签名,所以这次它不是根证书!

Is it possible that Google.com returns two different certificate chains, depending on which client does the request? Google.com 是否有可能根据请求的客户端返回两个不同的证书链? If it supposes that the client accepts the GTS Root R1 as root certificate, it returns this one, else it returns one signed by GlobalSign nv-sa ?如果它假设客户端接受GTS Root R1作为根证书,它返回这个,否则它返回一个由GlobalSign nv-sa签名的?

If so, why?如果是这样,为什么?

The following is the chain with the certificates and their digest/sha256.以下是带有证书及其摘要/sha256 的链。 Now when I look at the certificate chain in the browser, the first two have the same digest / sha-256 , but the third one has a different digest .现在,当我在浏览器中查看证书链时,前两个具有相同的digest / sha-256 ,但第三个具有不同的digest So I definitely think I'm getting a different chain depending on the client...所以我绝对认为我会根据客户获得不同的链条......

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'>

The python code I used to fetch the certificate:我用来获取证书的 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)

So thanks to President James K. Polk I think I better understand what's happening:所以感谢President James K. Polk ,我想我更好地理解正在发生的事情:

  • according to https://pki.goog/repository/ , there are two versions of the GTS Root R1 certificate with the same public key:根据https://pki.goog/repository/ ,具有相同公钥的GTS Root R1证书有两个版本:
    • A root certificate GTS Root R1根证书GTS Root R1
    • An intermediate certificate GTS Root R1 Cross , signed by GlobalSign nv-sa , which is a root certificate.中间证书GTS Root R1 Cross ,由GlobalSign nv-sa签名,是根证书。

So the browser receives the certificate chain as given in the question.因此,浏览器会收到问题中给出的证书链。 Then it tries to find the root certificates not only for the last element, Certificate #2 in the example above, but also for the previous elements.然后,它不仅会尝试查找最后一个元素(上例中的Certificate #2 )的根证书,还会尝试查找前面的元素的根证书。

In the example of google.com, it finds that it has a root certificate for the Certificate #1 and uses this one, ignoring the Certificate #2 .在 google.com 的示例中,它发现它具有Certificate #1的根证书并使用此证书,而忽略Certificate #2 Even though I'm not really sure why it does this:即使我不确定它为什么这样做:

  • does it hope to get rid of the GlobalSign certificate at some time?它是否希望在某个时候摆脱GlobalSign证书?
  • is it for redundancy?是为了冗余吗? If one certificate gets revoked, the other still works?如果一个证书被吊销,另一个证书仍然有效吗?

Also, the GTS Root R1 intermediate certificate is called GTS Root R1 Cross in the list above.此外, GTS Root R1中间证书在上面的列表中称为GTS Root R1 Cross But the digest is the same.但是摘要是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM