Я пытаюсь понять, как именно работает HTTPS, и делаю небольшие практические тесты.
У меня есть данные, полученные из HTTPS-связи, зашифрованные TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA.
Если я правильно понял, клиент во время рукопожатия TLS создает главный ключ, который затем шифруется с использованием открытого ключа сервера и отправляется на сервер. Этот мастер-ключ (в виде простого текста) затем используется в качестве симметричного ключа для шифрования текущей связи. Это правильно?
Если да, то как расшифровать данные, если я знаю главный ключ?
Сначала это звучало довольно легко, поэтому я просто написал этот сценарий
$masterKey = '8ef36f0eb2c10ea6142693374f6c5c7ae65eee5f6bd45bd1990b08e6c144227382726496b795d62284bd8c6c0cadbbdb';
$someRandomEncryptedData = '170303001D314A69C7DF95E07AAF51FBDA01C178D45330BC902308DF8C418FA5B02B';
$sDecrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, pack('H*', $masterKey), pack('H*', $someRandomEncryptedData), MCRYPT_MODE_CBC);
echo $sDecrypted;
Затем я замечаю, что главный ключ имеет длину 96 байт (48 в виде двоичной строки), что приводит к предупреждению PHP, поскольку ключ должен иметь длину 256 бит (32 байта). Я что-то пропустил?
клиент во время запроса создает главный ключ, который затем шифруется с использованием открытого ключа сервера и отправляется на сервер. Этот мастер-ключ (в виде простого текста) затем используется в качестве симметричного ключа для шифрования текущей связи. Это правильно?
Ну, в общем, нет.
Потому что вы спрашиваете о DH и ECDH, которые являются протоколами Соглашения о ключах: клиент делает не создать случайный ключ, зашифровать его под открытым ключом сервера и затем отправить его на сервер. Это ключевой транспорт (например, RSA Key Transport), и не DH или ECDH. Ключевой транспорт уходит в TLS 1.3.
TLS состоит из двух этапов: согласование ключей и массовая передача. Фазы не так хорошо определены, как в IPSec. Когда клиент и сервер используют DH или ECDH, они приходят к premaster_secret
, Это общий секрет выпадения Диффи-Хеллмана или Эллиптической кривой Диффи-Хеллмана.
Они берут premaster_secret
, они добавляют случайный клиент, случайный сервер и получают master_secret
, Затем они принимают master_secret
и выведите из него 6 симметричных ключей:
Эти ключи используются для ввода блочного или потокового шифра.
Если вы заметили, каждая сторона вносит свой вклад в premaster_secret
— клиент вносит свой вклад g^a
и сервер вносит свой вклад g^b
, Тогда каждая сторона вносит свой вклад в master_secret
через одноразовые номера — клиент случайный и сервер случайный.
Причина, по которой есть два вклада с обеих сторон, заключается в том, что транспортные схемы, такие как RSA Key Transport, не позволяют серверу вносить вклад в premaster_secret
, Сервер должен ждать до получения master_secret
внести свой вклад в материал ключа через одноразовый номер.
Так что прогрессия premaster_secret
в master_secret
до 6 сеансовых ключей. Я не уверен, где находится главный ключ …
Если да, то как расшифровать данные, если я знаю главный ключ?
Я думаю, что обычно проще подключить его к Wireshark, если у вас есть мастер-ключ. Вики Wireshark рассказывают о главном ключе (хотя я не знаю, что это такое — есть premaster_secret
а также master_secret
). Смотрите вики Wireshark для Secure Socket Layer (SSL).
Сначала это звучало довольно легко, поэтому я просто написал этот сценарий
Да … 🙂 Проверьте RFC 5246. Это Протокол безопасности транспортного уровня (TLS) версии 1.2. Тогда давайте поговорим о легком 🙂
Затем я замечаю, что главный ключ имеет длину 96 байт (48 в виде двоичной строки)
96 байтов является выходом функции псевдо-случайного выбора (PRF). Ознакомьтесь с RFC 5246, стр. 13.
Других решений пока нет …