Я здесь"что происходит в первые несколько миллисекунд соединения https«Подробно описывает процесс https-подключения. В этой статье анализируется весь процесс с помощью инструмента захвата пакетов. В этой статье основное внимание будет уделено процессу шифрования и дешифрования с точки зрения исходного кода Chrome, а также добавлены дополнительные сведения.
Chrome/Chromium используетBoringSSLВ качестве библиотеки для слоя TLS этоOpenSSLФорк Chrome изменен на openssl для адаптации к характеристикам собственных продуктов, код находится вsrc/third_party/boringssl/.
Первый шаг подключения HTTPS -Отправить привет клиенту, браузер заполняет сообщение Client Hello используемой версией TLS, случайным числом клиента, списком шифрования (наборы шифров) и расширением, содержащим имя хоста.
Всего браузеры поддерживают 5 версий TLS:
#define SSL3_VERSION 0x0300 // 3.0
#define TLS1_VERSION 0x0301 // 3.1
#define TLS1_1_VERSION 0x0302 // 3.2
#define TLS1_2_VERSION 0x0303 // 3.3 (TLS 1.2)
#define TLS1_3_VERSION 0x0304 // 3.4 (TLS 1.3)
Последней версией является TLS 1.3, в настоящее время поддерживается только Chrome и Firefox, поддерживается nginx 1.13 (нестабильная версия)/cloudflare, и в настоящее время наиболее широко используемой версией является TLS 1.2. Chrome устанавливает TLS на 1.2 в Client Hello:
// hs为SSL_HandShake
hs->client_version =
hs->max_version >= TLS1_2_VERSION ? TLS1_2_VERSION : hs->max_version;
В дополнение к TLS есть DTLS, поддерживающий UDP:
#define DTLS1_VERSION 0xfeff
#define DTLS1_2_VERSION 0xfefd
Набор шифров печатного списка шифрования состоит из 13:
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
Это метод шифрования, поддерживаемый браузером, поместите его в Client Hello и отправьте на сервер для выбора. Каждый из вышеперечисленных методов шифрования представлен двухбайтовым цифровым числом, например, первое число — 0xc02B, это вRFC5289положения, подлежащие выполнению.
Что означает этот длинный список зашифрованных имен? Возьмем в качестве примера TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, как показано на следующем рисунке:
Обмен ключами использует алгоритм ECDHE, аутентификация службы использует алгоритм RSA, шифрование передачи данных использует AES (+GCM), а рукопожатие использует проверку SHA256.
Другими словами, сертификат подписан с использованием RSA, и если сертификат проверен правильно, алгоритм ECDHE будет использоваться для обмена ключами, чтобы гарантировать, что браузер и сервис имеют один и тот же закрытый ключ, а затем одна сторона использует этот ключ для Шифрование данных AES, а другая сторона использует этот ключ для шифрования данных AES.Используйте тот же ключ для расшифровки данных AES. Проверка действительности подписи сертификата и подтверждение личности при обмене ключами осуществляется с использованием хеш-алгоритма SHA256. Конкретный процесс описан ниже.
Далее сервер выполняетServer HelloОтвет, включая версию TLS, которую должен использовать сервер, когда мы посещаем google.com, Google возвращает версию TLS 1.2 (0x303, что равно 771 в десятичном виде):
Если служба возвращает версию TLS 1.3, Chrome будет использовать версию 1.3.
Server Hello также возвращает 32-байтовое случайное число сервера random, которое похоже на случайное число случайного числа, отправленное браузером.Это случайное число называется nonce и используется для одноразового использования, обычно с отметкой времени, и мастер будет сгенерирован позже и использован при использовании ключа.
Он также вернет идентификатор сеанса, чтобы повторно использовать информацию о текущем рукопожатии в следующий раз, чтобы избежать повторных рукопожатий в течение короткого времени.
При этом возвращается выбранный метод шифрования, как показано на следующем рисунке:
Сервер Google использует метод шифрования, показанный выше. Согласно наблюдениям, этот метод также используется многими серверами. Это должен быть лучший метод, который сочетает в себе безопасность и вычислительную сложность. Узнав метод шифрования (в том числе и то, что сертификат подписан RSA), после получения сертификата от сервиса прочитайте сертификат иПроверить действительность сертификата.
Проверка сертификата осуществляется самостоятельно через Post a Task в поток TaskScheduler.Другие операции рукопожатия выполняются в потоке IO Chrome.Следует учитывать, что проверка сертификата сложная, поэтому она сделана асинхронной.
Проверка сертификата Chrome не использует API, предоставляемый BoringSSL, а реализует его самостоятельно в каталоге src/net/cert. Процесс такой.Сначала проверит есть ли он в черном списке.Черный список выглядит следующим образом в комментариях к исходному коду:
// CloudFlare revoked all certificates issued prior to April 2nd, 2014. Thus
// all certificates where the CN ends with ".cloudflare.com" with a prior
// issuance date are rejected.
//
// The old certs had a lifetime of five years, so this can be removed April
// 2nd, 2019.
Общая идея заключается в том, что общее имя сертификата (обычно доменное имя сертификата) — это сертификат, оканчивающийся на .cloudflare.com, и он был выпущен до 2014.4.2 и был аннулирован.Эти сертификаты действительны в течение 5 лет. и все еще находятся в периоде действия, поэтому его необходимо считать недействительным.
Затем проверьте действительность подписи сертификата, которая выполняется системной функцией SecTrustEvaluate, вызываемой Chrome на Mac. В процессе осмотра нахожусь в "что происходит в первые несколько миллисекунд соединения https«Это было представлено подробно. Вообще говоря, сначала выполните SHA256 для сертификата, чтобы получить хеш-значение, а затем расшифруйте подпись сертификата с помощью открытого ключа сертификата, чтобы получить другое хеш-значение, если два хеш-значения равны. , что указывает на то, что сертификат не был подделан и действительно выдан уполномоченным органом.
Вообще говоря, так называемаяцифровой подписи, заключается в создании хэша отправленного содержимого, а затем получатель использует содержимое для вычисления значения хеш-функции. Если это значение равно хешу в подписи, это означает, что содержимое не было изменено третьей стороной. . И эта подпись обычно зашифрована.В сертификате подпись зашифрована с помощью закрытого ключа сертификата.Любой может расшифровать ее с помощью открытого ключа, указанного в сертификате, но любойНевозможно правильно зашифровать без закрытого ключа, поскольку закрытый ключ и открытый ключ соединяются один за другим, если вы шифруете другим закрытым ключом, а затем расшифровываете исходным открытым ключом, это не должно быть исходным содержимым.
Следовательно, если проверка подписи верна, то отправленный контент, то есть сертификат, является законным (сертификат содержит такую информацию, как доменное имя, открытый ключ и т. д.). Если проверка этого шага недействительна, будет возвращена ошибка CERT_STATUS_AUTHORITY_INVALID.
Затем проверьте, совпадает ли Общее имя, указанное в сертификате, как показано на следующем рисунке:
Текущее имя хоста — www.google.co.kr, а общее имя в сертификате — *.google.co.kr:
www.google.co.kr включен в подстановочный знак *.google.co.kr, поэтому этот тест пройден. Если не через браузер, будет отображаться ошибка CERT_STATUS_COMMON_NAME_INVALID.
Относительно этого подстановочного знака есть небольшая деталь. Если подстановочный знак является доменным именем верхнего уровня, например *.com, он считается незаконным, и разрешены только частные зарегистрированные домены: (Этот тип сертификата, который поддерживает пандоменные имена будет дороже, чем те, которые поддерживают только фиксированные доменные имена)
// Do not allow wildcards for public/ICANN registry controlled domains -
// that is, prevent *.com or *.co.uk as valid presented names, but do not
// prevent *.appspot.com (a private registry controlled domain).
Затем проверьте, находится ли сертификат в общедоступном черном списке:
Если да, верните статус отозванного сертификата: CERT_STATUS_REVOKED, эти черные списки видныblacklist. Эти черные списки включают Китайский сетевой информационный центр Интернета (CNNIC) и т. д. Из-за небезопасности, вызванной фиксированным открытым ключом, пожалуйста, обратитесь к описанию ссылки, прикрепленной к документу, для получения подробной информации.
Затем снова проверьте, использует ли сертификат слабым алгоритмом подписи, такой как SHA1 / MD5:
Если это так, верните CERT_STATUS_WEAK_SIGNATURE_ALGORITHM, потому чтоИ SHA1, и MD5 считаются небезопасными алгоритмами хеширования., уязвим к атакам коллизии (например, 23 февраля 2017 г. Google объявила об успешной атаке коллизии SHA-1 и выпустила два файла PDF с разным содержимым, но с одним и тем же значением хеш-функции SHA-1 в качестве доказательства концепции, подробности см.Википедия).
Затем проверьте, выдан ли сертификат Symantec:
// Distrust Symantec-issued certificates, as described at
// https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
Если он выдан Symantec, доверие будет отменено в версии Chrome 66 (стабильная версия 2018.4.17).Symantec является одним из крупнейших мировых центров сертификации.Его корневые сертификаты включают GeoTrust, VeriSign и т. д.:
Почему Google хочет не доверять ему,гугл блогВот что он говорит:
During the subsequent investigation, it was revealed that Symantec had entrusted several organizations with the ability to issue certificates without the appropriate or necessary oversight, and had been aware of security deficiencies at these organizations for some time.
Общая идея заключается в том, что после расследования оно произвольно назначило несколько агентств для выдачи сертификатов без надзора. Когда мы открываем некоторые веб-сайты, консоль предлагает:
The SSL certificate used to load resources from https://***.com will be distrusted in M70. Once distrusted, users will be prevented from loading these resources. See https://g.co/chrome/symantecpkicerts for more information.
Это потому, что они используют сертификат, выданный GeoTrust.
Chrome также выполняет другие проверки, в том числе, не слишком ли велик срок действия сертификата, как указано в следующем исходном коде:
// For certificates issued after 1 July 2012: 60 months.
// For certificates issued after 1 April 2015: 39 months.
// For certificates issued after 1 March 2018: 825 days.
И является ли формат самого сертификата законным (CERT_STATUS_INVALID) и так далее. Если это расширенный сертификат EV, существуют специальные проверки, а некоторые сертификаты необходимо проверять с использованием протокола статуса онлайн-сертификата (OCSP).
Проверка валидности сертификата и рукопожатие (HandShake) выполняются синхронно, поскольку выполняется в отдельном потоке. Обычно после Server Hello сервис отправляет сертификат в браузер для проверки, а следующий шаг выполняется после успешной проверки.Возможно, Chrome считает проверку трудоемкой, поэтому ее делают асинхронной.
Во всяком случае, после Server Helloобмен ключами, целью обмена ключами является обмен ключами для обеих сторон и использование одного и того же ключа для шифрования и дешифрования. Существует два метода обмена ключами: RSA и ECDHE. Метод RSA относительно прост. Браузер генерирует ключ, затем шифрует его с помощью открытого ключа сертификата RSA и отправляет на сервер. Затем сервис использует свой ключ. чтобы расшифровать его.Ключ, так что ключ может быть передан, его недостаток заключается в том, что, хотя злоумышленник не может взломать его в процессе отправки, если он сохраняет все зашифрованные данные, закрытый ключ не сохраняется до истечения срока действия сертификата.Если он происходит утечка, то он может использовать этот закрытый ключ для расшифровки всех данных, которые были переданы ранее. Использование ECDHE является более безопасным алгоритмом обмена ключами.
Полное название ECDHE — обмен ключами Диффи-Хеллмана на эллиптических кривых, который представляет собой вариант обмена ключами Диффи-Хеллмана и использует шифрование на основе эллиптических кривых для повышения безопасности.
Процесс обмена ключами Диффи-Хеллмана выглядит следующим образом: обе стороны A и B выбирают базу g, например g = 2, затем A и B генерируют свои собственные ключи a и b, а A отправляет A = g ^a и g передаются B, и B вычислит общий ключ K = A ^ b = g^(ab) после его получения и отправит B = g ^ b в A, так что A также может получить общий ключ K = B ^ а = г ^ (аб). Как показано ниже:
Поскольку A и B обычно очень большие, повышение A или B до власти будет астрономическим числом, поэтому он должен быть модуль большой простым р.
Подслушиватель может знать g, A и B, но не знает ни ключа a, ни b стороны, поэтому он не может знать, что такое общий ключ K. Чтобы гарантировать, что передаваемая информация не может быть подделана, данные обмена ключами должны быть подписаны с помощью RSA сертификата. Более подробное описание см.Википедия.
Благодаря передаче расчетного значения мощности легче взломать, чтобы получить соответствующие ключи обеих сторон.Такой коэффициент безопасности не очень высок, поэтому вводится шифрование кривой эллипса ECC. ECC и RSA также могут использоваться в качестве алгоритма шифрования сертификатов.Общая черта ECC и RSA заключается в том, что шаги шифрования очень просты, но расшифровка очень сложна.Сложность RSA состоит в том, чтобы разделить большое число на два простых числа. числа и умножать их, а ECC Трудность заключается в нахождении коэффициентов точки. Разница в том, что ECC гораздо труднее взломать, чем RSA.Например, сложность взлома 2048-битного RSA эквивалентна сложности 224-битного ECC.Чем короче длина, тем меньше потребление ресурсов процессора и выше скорость . ECC широко используется в случаях шифрования высокого уровня. Все больше и больше сертификатов используют шифрование ECC. Например, доменные имена *.google.com используют сертификаты с шифрованием EC. По сравнению с 2048-битными открытыми ключами других сертификатов RSA сертификаты EC имеют только 256 бит:
В частности, так называемая эллиптическая кривая относится к следующему уравнению:
y^3 = x ^ 2 + ax +b
Как показано ниже:
Рисунок состоит из начальной точки P, вычисляет 2P--, чтобы провести прямую, касательную к точке P, и точки пересечения кривой -2P, чтобы эта точка пересечения кривой отражала 2P, 3P вычисляется как 2P + P, следующим образом ФИГ соединяется с П и 2П, а третья кривая является пересечением -3П, 3П :( получается отражение произвольной прямой и эллиптической кривой только до трех пересечений)
И так далее, 4P = 3P + P, отражение, соединяющее пересечение 3P и P с кривой, есть 4P. Если последняя линия перпендикулярна оси x после n раз, это означает, что все точки были израсходованы, и всего точек (или порядка) n. В этом процессе вычисления будет взято большое число p в качестве модуля. Когда значение координаты точки больше p, оно модулируется. Начальная точка P(x, y) называется точкой-генератором, а два коэффициента ab параметров уравнения - {a, b , порядок, x, y} образуют Основные параметры группы эллиптических кривых.
Сложность эллиптических кривых заключается в том, что для заданных точек P и Q, Q = kP (1
Таким образом, процесс обмена ключами с использованием шифрования на основе эллиптических кривых становится следующим:
Посредник или перехватчик может знать Q1 и Q2, коэффициенты уравнения a, b и начальную точку P, но он не может вывести соответствующие ключи x, y двух сторон, поэтому он не может вычислить общий ключ K = xyP . И трудность этого взлома намного больше, чем при использовании силы. Это ЭКДЭ. Для более подробной информации вы можете проверить этовидеоурок.
В реальной реализации базовые параметры передаются не при обмене ключами, а по согласованной фиксированной кривой.В процессе отладки мы обнаружили, что Chrome поддерживает всего 3 вида кривых:
static const uint16_t kDefaultGroups[] = {
SSL_CURVE_X25519,
SSL_CURVE_SECP256R1,
SSL_CURVE_SECP384R1,
};
www.google.co.kr использует Curve X25519,X25519Используемое уравнение кривой:
y^2 = x^3 + 486662x2 + x
А *.google.com использует Curve secp256r1, именуемый P-256, который находится вServer Key ExchangeВ нем указано:
Его группа параметров выглядит следующим образом:
Если преобразовать в десятичную:
a = 115792089129476408780076832771566570560534619664239564663761773211729002495996
b = 99593677540221402957765480916910020772520766868399186769503856397241456836063
n = 115792089210356248762697446949407573529996955224135760342422259061068512044369
Мы видим, что n — 78-битное число, поэтому перебор k (P = kG, 1
После определения основного уравнения значения Q1 и Q2 обеих сторон обмениваются в виде открытых ключей в обмене ключами сервера и обмене ключами клиента.
Чтобы гарантировать, что обмен ключами не может быть изменен, необходимо выполнить подпись.Если подпись использует RSA, метод такой же, как и при проверке действительности сертификата. Если сертификат является сертификатом EC, он будет подписан с помощью ECDSA (ecdsa_secp256r1_sha256(0x0403,)):
Конкретной функцией проверки является используемая функция ECDSA_do_verify.Описание процесса см.Википедия, есть много шагов, и я не буду подробно обсуждать их здесь. Сертификат EC также имеет открытый ключ и секретный ключ.Окончательный стандарт проверки заключается в том, что значение r в подписи, расшифрованной с помощью открытого ключа, равно значению, рассчитанному вручную, что означает, что оно правильное.
тогдаClient Key Exchange, Chrome использует соответствующие параметры и алгоритмы для генерации открытого ключа и пары ключей в соответствии с типом кривой (x25519 или P-256).Например, ключ X25519 генерируется с использованием случайных чисел:
С помощью ключа вычислите соответствующий открытый ключ, затем сохраните открытый ключ и отправьте его, а затем вычислите общий ключ.Основной код должен состоять из следующих строк:
// Compute the x-coordinate of |peer_key| * |private_key_|.
EC_POINT_mul(group.get(), result.get(), NULL, peer_point.get(),
private_key_.get(), bn_ctx.get()
Используйте открытый ключ другой стороны peer_key * собственный закрытый ключ private_key_, чтобы получить K = yQ1.
Затем используйте этот общий ключ для передачиPRFРассчитать отмычку мастер-ключ. Мы можем распечатать ключ, полученный из рукопожатия, следующим образом:
连接域名:www.google.com
加密方式:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
曲线名称:SSL_CURVE_X25519
Peer Public Key (64B): 8b4364a862a7a7f19404973237079b692c1208b8ecf7828d9eae2b76e68e5012
Chrome Public Key (64B): cddd4c2d0c9d49903438a953076fb3baebd38cfa4a3b18144365b67756b4c075
Share Key (78B): 653d6e28202ff88dff92db77c91406b7992a0f15325b0192f17a317e7ff71930404dc7d4857f03
Master Key (96B): eb584819ae738a45fe9a2e60734d0ae833dfb2d63a1900ee820a36db27a3844e5b6259e2c84e06fd1474c7e1857989ad
连接域名:www.baidu.com
加密方式:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
曲线名称:SSL_CURVE_SECP256R1
Peer Public Key (142B): 04ac277ce63eb420e9e973c96cdf67e37a5956b949af4b053ca5b1b4b1f884b7f6cadbe2d64a91d43a2e280da528d6b6505bc6be10455e70aeabe569562ccc7bdebc7b5df80705
Chrome Public Key (130B): 04941ec80392f0bf13268a9791e7ee673df0a00af6e59335655b0519fbc575bfcb39eabd80f81118dca4906f776c801aee26f8f4fc195917dc94f9c324886bebc4
Share Key (78B): 52d0f6fc4ecd83107fb8c1cc7fa3f978152c0936c58d8d62d6885f7a672cf87c21212121212103
Mater Key (96B): 1e95a25c356a170c6829ec27a0216c50738b758f93606e8503a2e306796fd99db6ec49f65818a125bba6449b07648262
После обмена ключами обе стороны уже имеют одинаковый ключ, а затем отправляютChange Cipher SpecУведомить другую сторону о том, что следующий пакет будет зашифрован ранее согласованным методом. Поскольку в передаваемых данных указано шифрование GCM, этоAEADChrome настроит AEAD в процессе смены шифра.Особенностью этого метода шифрования является добавление к данным метки аутентификации.Если метка совпадает, значит данные не повреждены.
В этот момент все рукопожатие TLS завершается, затем отправляется HTTP-запрос и принимаются данные ответа.
Характеристика шифрования AES, используемого при передаче данных, заключается в использовании ключа для шифрования и последующего использования того же ключа для расшифровки. Однако мы можем распечатать данные до и после шифрования, как показано на следующем рисунке:
Видно, что это HTTP-запрос, данные до шифрования — 572Б, данные после шифрования — 601Б, а объем увеличился на 5%.
Этот запрос получает следующие расшифрованные данные ответа:
Ниже также приведены данные, сжатые с помощью gzip.
До сих пор этот процесс объясняется. Эта статья ориентирована на то, насколько Chrome проверяет достоверность сертификата, то, как это алгоритм Ellipeman, как эллиптическая кривая зашифрована, как использовать ECDHE для обмена ключами и так далее. Многие вещи в этой статье не объясняются в глубине, но все они указаны. После прочтения этой статьи вы должны иметь общее понимание всего процесса шифрования HTTPS и иметь некоторое понимание принципов некоторых алгоритмов шифрования.
Связанное чтение:
- Почему вы должны обновить свой сайт до HTTPS
- что происходит в первые несколько миллисекунд соединения https