Возвращает ли Google разные сертификаты для разных клиентов?

#python #ssl #ssl-certificate #root-certificate

#python #ssl #ssl-сертификат #root-сертификат

Вопрос:

для класса я просматриваю цепочку сертификатов TLS google.com . Когда я нажимаю в браузере Chrome или Firefox, корневой сертификат отображается как GTS Root R1 со сроком действия до 2036 года, самоподписанный, поэтому он должен быть корневым сертификатом.

Однако, если я проверю то же самое в Python, используя следующий код, я получу GTS Root R1 сертификат со сроком действия 2028, который подписан GlobalSign nv-sa , так что на этот раз это НЕ корневой сертификат!

Возможно ли, что Google.com возвращает две разные цепочки сертификатов, в зависимости от того, какой клиент выполняет запрос? Если предполагается, что клиент принимает GTS Root R1 корневой сертификат as, он возвращает этот сертификат, иначе он возвращает подписанный GlobalSign nv-sa ?

Если да, то почему?

Ниже приведена цепочка с сертификатами и их дайджестом / 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.2nn')
    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)
 

Комментарии:

1. Вполне вероятно, что в обоих случаях отправляется одна и та же цепочка сертификатов, просто проверка цепочки браузера остановится на первом доверенном сертификате, который на платформе, на которой вы запускаете браузер, является GTS Root R1. Если вы временно удалите этот сертификат из списка доверенных сертификатов вашей платформы (но убедитесь, что Globalsign все еще существует) и повторно подключитесь к браузеру, вы увидите полную цепочку.

2. Я обновил вопрос с помощью цепочки, которую я получаю от python. Когда я смотрю на цепочку в браузере, только два первых сертификата имеют одинаковый дайджест. У третьего есть другой дайджест, поэтому он определенно отправляет другой сертификат при запросе браузером.

3. «Цепочка в браузере …» Я хочу сказать, что цепочка, которую вы видите отображаемой браузером, не совсем та цепочка, которая отправляется.

4. Я только что подтвердил это с помощью теста. В обоих случаях отправляется одна и та же цепочка, браузер просто отображает другой корневой сертификат в соответствии с процедурами проверки цепочки.

Ответ №1:

Итак, благодаря President James K. Polk , я думаю, я лучше понимаю, что происходит:

  • согласно https://pki.goog/repository /, существует две версии GTS Root R1 сертификата с одним и тем же открытым ключом:
    • Корневой сертификат 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 /

Комментарии:

1. Проверка цепочки сертификатов сложна, но упрощенная версия такова: начните с конечного сертификата. Является ли он правильно сформированным, разумным и не истекшим? Выдается ли он сертификатом, которому я уже полностью доверяю ? Если да, то мы закончили. В противном случае является ли эмитент следующим сертификатом в цепочке? Если да, повторите все эти тесты с этим сертификатом и так далее

2. надеется ли он когда-нибудь избавиться от сертификата GlobalSign? Да, именно поэтому. Получение нового корневого сертификата в экосистему PKI — сложный и длительный процесс. Поскольку это происходит, будут некоторые платформы, на которых ваш root является надежным, а другие — нет. В течение этого переходного периода вам необходимо, чтобы ваш корневой сертификат был подписан уже широко доверенным корневым сертификатом и был развернут точно так же, как это сделано в вашем примере. Один вопрос: зачем Globalsign помогать конкуренту? «За деньги» — это один из ответов. Реальность сложнее.