0,0
рейтинг
30 августа 2013 в 07:40

Разработка → Первые несколько миллисекунд HTTPS соединения перевод

После нескольких часов чтения обзоров, Боб с нетерпением нажал на кнопку перехода к оформлению заказа на галлон цельного молока, и…
Воу, что только что произошло?



За 220 миллисекунд произошло множество интересных вещей, из-за которых Firefox сменил цвет адресной строки и отобразил замочек в правом нижнем углу. С помощью моего любимого инструмента Wireshark и немного модифицированной отладочной сборки Firefox мы попробуем разобраться, что же именно произошло.
По RFC 2818 Firefox знает, что «https» означает, что нужно использовать 443 порт для подключения к Amazon.com:



Приветствие клиента


TLS заворачивает весь траффик в «записи» различных типов. Мы видим, что первый байт пакета в HEX равен 0x16 = 22, что означает, что «запись» является «рукопожатием»:



Следующие два байта — 0x0301, означающие версию 3.1, что говорит о том, что TLS 1.0 на самом деле SSL 3.1.
Запись с рукопожатием разбита на несколько сообщений. Первый — «приветствие клиента» (0x01). Здесь есть несколько важных моментов:

  • Случайность:


    Эти четыре байта — текущее Unix time, количество секунд с 1 Января, 1970. В нашем случае это 0x4a2f07ca. За ними идут 28 случайных байт, которые понадобятся позже.
  • ID сессии:


    В нашем случае это поле пусто. Если бы мы подключались к Amazon.com несколькими секундами ранее, то могли бы продолжить сессию и не проводить полное рукопожатие.
  • Cipher Suites:


    Список всех поддерживаемых браузером алгоритмов шифрования. По умолчанию используется очень сильный «TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA», за которым идут ещё 33 варианта. Не волнуйтесь, если ничего не понимаете. Далее мы узнаем, что Amazon не примет наш вариант по умолчанию.
  • Расширение server_name:


    Способ сказать amazon.com, что браузеру нужна страница по адресу www.amazon.com. Это довольно удобно, потому что TLS рукопожатие начинается задолго до HTTP траффика. В HTTP есть заголовок «Host», позволяющий хостить сотни сайтов на одном IP. SSL традиционно требовал разные IP для разных сайтов, но это расширение позволяет серверу отвечать сертификатом конкретного сайта.

Приветствие сервера


Amazon.com отвечает довольно крупной записью с рукопожатием, размером в два пакета (2,551 байт). В ней указана та же последовательность байт 0x0301, что означает согласие Amazon использовать TLS 1.0. В записи есть три подсообщения с интересными данными:

  1. Сообщение «Приветствие сервера»:


    • Четыре байта Unix time и 28 случайных байт.
    • ID сессии в 32 байтах для ускорения следующих запросов.
    • Из 34 алгоритмов, предложенных нами, Amazon выбрал «TLS_RSA_WITH_RC4_128_MD5» (0x0004). Это означает, что будет использоваться алгоритм RSA для проверки подписей сертификата и обмена ключами, алгоритм RC4 для шифрования данных, хэш функция MD5 для проверки содержимого. Мы обсудим всё это более подробно позже. Мне кажется, у Amazon есть свои причины для выбора именно этих алгоритмов, например, снижение нагрузки на CPU. Менее вероятный вариант — благодарность Ron Rivest, создателю всех трёх вышеуказанных алгоритмов.

  2. Сообщение с сертификатом:


    • Огромное сообщение в 2.464 байта и его сертификат, который клиент может использовать для валидации сертификата Amazon. Всё это также можно посмотреть в браузере.

  3. Сообщение «Приветствие сервера выполнено»


    Пустое сообщение, сообщающее об успешном завершении «приветствия» и говорящее о том, что сервер не будет запрашивать сертификатов клиента.

Проверка сертификата


Сертификаты нужны для того, чтобы браузер мог удостовериться, что общается именно с Amazon.com. Он смотрит на даты начала и окончания срока действия сертификата, а также проверяет, авторизован ли публичный ключ для обмена секретными ключами.

Почему мы должны доверять сертификатам?

К нему прикреплена «подпись», длинное число в формате big-endian:
Кто угодно мог прислать эти байты. Почему мы должны доверять этой подписи? Для ответа совершим небольшое путешествие в мир математики:

Небольшое введение в RSA


Некоторые люди задаются вопросом, имеет ли математика какую либо связь с программированием? Сертификаты — очень наглядный случай применения математики. Сертификат Amazon говорит нам, что нужно использовать RSA для проверки подписи. RSA был создан в 1970 профессорами MIT Ron Rivest, Adu Shamir и Len Adleman, нашедшими красивый способ соединить идеи, появившиеся за 2000 лет развития математки и создать простой алгоритм:

Вы выбираете два простых числа, p и q. Умножаете их и получаете n. Далее, вы выбираете простую публичную экспоненту e, которая будет шифрующей экспонентой, и специально подобранную обратную e, d, которая будет дешифрующей. Затем вы делаете n и e публичными и храните d в секрете. Про p и q можно забыть, или же хранить вместе с d.

Теперь, если у вас есть сообщение, вам нужно просто представить его байты как число M. Если нужно зашифровать сообщение, высчитываем:

C ≡ Me (mod n)

Это означает, что нужно умножить M на себя e раз. mod n означает, что мы берём только остаток от деления на n. Например, 11 AM + 3 часа = 2PM (mod 12 часов). Получатель знает d и может произвести обратную операцию для расшифровки:

Cd ≡ (Me)d ≡ Me*d ≡ M1 ≡ M (mod n)

Также интересно, что человек с d может подписать документ возведя сообщение M в степень d:

Md ≡ S (mod n)

Это возможно благодаря тому, что подписывающая сторона делает публичными S, M, e и n. Кто угодно может проверить подпись S с помощью простых вычислений:

Se ≡ (Md)e ≡ Md*e ≡ Me*d ≡ M1 ≡ M (mod n)

Криптография с публичным ключом часто называется асимметричной, потому что ключ шифрования (в нашем случае e) не равен ключу дешифровки (d). Магия RSA работает из-за того, что вы можете рассчитать C ≡ Me (mod n) довольно быстро, но почти невозможно Cd ≡ M (mod n) не зная d. Как мы уже убедились ранее, d полуается из факторизации n обратно к p и q, что довольно-таки сложно.

Проверка подписей


Работая с RSA в реальной жизни важно помнить, что все числа должны быть __очень__ большими. Насколько? Сертификат Amazon подписан «VeriSign Class 3 Secure Server CA». Это значит, что n должно быть 2048 бит длинной, что в десятичном виде:

1890572922 9464742433 9498401781 6528521078 8629616064 3051642608 4317020197 7241822595 6075980039 8371048211 4887504542 4200635317 0422636532 2091550579 0341204005 1169453804 7325464426 0479594122 4167270607 6731441028 3698615569 9947933786 3789783838 5829991518 1037601365 0218058341 7944190228 0926880299 3425241541 4300090021 1055372661 2125414429 9349272172 5333752665 6605550620 5558450610 3253786958 8361121949 2417723618 5199653627 5260212221 0847786057 9342235500 9443918198 9038906234 1550747726 8041766919 1500918876 1961879460 3091993360 6376719337 6644159792 1249204891 7079005527 7689341573 9395596650 5484628101 0469658502 1566385762 0175231997 6268718746 7514321
(Удачи с подбором p и q. Если получится — можно сгенирировать поддельный VeriSign сертификат.)

Если мы возведём подпись S в степень публичного e VeriSign, а затем возьмём остаток от деления на модуль n, то получим расшифрованную подпись в hex:

0001FFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFF00302130 0906052B0E03021A 05000414C19F8786 871775C60EFE0542 E4C2167C830539DB

По стандарту PKCS #1 v1.5, первый байт 00 для того, чтобы блок шифрования, сконвертированный в integer, был меньше, чем модуль(так и не понял, что за модуль — прим. перев.). Второй байт 01 указывает на то, что это операция с приватным ключом. Затем куча FF байт для того, чтобы забить пустое место. Завершается оно байтом 00, затем идёт последовательность «30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14», что означает применение SHA-1 функции. Последние 20 байт — результат SHA-1 от байт в signedCertificate.

Так как расшифрованное значение правильно отформатировано и последние байты соответствуют тем, что мы можем посчитать сами, мы можем предположить, что кто-то знающий приватный ключ «VeriSign Class 3 Secure Server CA» подписал это.

Можно повторить процесс и удостовериться в том, что сертифика «VeriSign Class 3 Secure Server CA» был подписан VeriSign «Class 3 Public Primary Certification Authority».

Но почему надо ему доверять? В этой цепочке доверия нет больше звеньев.



Корневой «VeriSign Class 3 Public Primary Certification Authority» был подписан сам собой. Этот сертификат встроен в продукты Mozilla как безоговорочно доверенный сертификат.

Pre-master Ключ


Мы проверили Amazon.com и знаем его публичную шифрующую экспоненту e и модуль n. Кто угодно прослушивающий нас может сделать то же самое. Теперь нам надо сгенерировать случайный ключ, который атакующий не узнает. Это не так просто как может показаться, из-за уязвимости псевдогенератора случайных чисел в Netscape Navigator 1.1 SSL можно было взломать за 25 секунд на машинах того времени. Если не верите, что настоящая случайность — это сложно, можете спросить мэинтейнеров OpenSSL в Debian.

На Windows, например, функция генерации псевдослучайных чисел берёт данные из 125 источников. Firefox использует её результат и добавляет несколько бит собственных псевдослучайных данных

Очень важно держать в секрете 48-байтовы «pre-master ключ», так как многие вещи выводятся именно из него. Не удивительно, что в Firefox так сложно его найти. Мне пришлось собрать отладочную версию и установить флаги SSLDEBUGFILE и SSLTRACE чтобы его увидеть

4456: SSL[131491792]: Pre-Master Secret [Len: 48]
03 01 bb 7b 08 98 a7 49 de e8 e9 b8 91 52 ec 81 ...{...I.....R…
4c c2 39 7b f6 ba 1c 0a b1 95 50 29 be 02 ad e6 L.9{......P)…
ad 6e 11 3f 20 c4 66 f0 64 22 57 7e e1 06 7a 3b .n.? .f.d«W~..z;

Он не совсем случаен, первые два байта по стандарту TLS должны быть 03 01.

Обмен ключами
Теперь нам надо передать это секретное число в Amazon.com. Так как Amazon пожелал использовать „TLS_RSA_WITH_RC4_128_MD5“, мы зашифруем его RSA. Можно использовать в качестве сообщения только 48 байт pre-master ключа, но по стандарту PKCS #1 v1.5 нужно забить пустое место случайными данными и довести размер пакета до 128 байт. Так будет сложнее расшифровать пакет атакующему.

Наконец, Firefox отправляет последнее незашифрованное сообщение, запись „Change Cipher Spec“:



Это способ Firefox сказать Amazon, что он собирается использовать переданные ранее секретные ключи для следующих сообщений.

Вычисление Master Secret

Если мы сделали всё верно, то обе стороны теперь знают 48 байт pre-master ключа. Со стороны Amazon есть лёгкое недоверие, так как pre-master содержит только данные клиента и не содержит данных сервера. Исправим это вычислив master key.

master_secret = PRF(pre_master_secret, „master secret“, ClientHello.random + ServerHello.random)

PRF — псевдорандомная функция, которая определена в спецификациях и довольно хитра. В ней используются HMAC версии MD5 и SHA-1. По половине ввода отправляется в каждую функцию, получается результат, весьма устойчивый к атакам.

В результате получаем 48 байт master secret.

4C AF 20 30 8F 4C AA C5 66 4A 02 90 F2 AC 10 00 39 DB 1D E0 1F CB E0 E0 9D D7 E6 BE 62 A4 6C 18 06 AD 79 21 DB 82 1D 53 84 DB 35 A7 1F C1 01 19

Генерируем остальные ключи

Теперь, когда у двух сторон есть master secret, по спецификации мы можем вычислить все нужные для сессии ключи используя PRF для создания „блока ключей“, из которого и возьмём нужные данные:

key_block = PRF(SecurityParameters.master_secret, „key expansion“, SecurityParameters.server_random + SecurityParameters.client_random);

Байты из „блока ключей“ нужны для:
client_write_MAC_secret[SecurityParameters.hash_size]
server_write_MAC_secret[SecurityParameters.hash_size]
client_write_key[SecurityParameters.key_material_length]
server_write_key[SecurityParameters.key_material_length]
client_write_IV[SecurityParameters.IV_size]
server_write_IV[SecurityParameters.IV_size]

Так как мы используем потоковое, а не блочное шифрование, нам не нужны векторы инициализации. Тем не менее, нам нужны два Message Authentication Code (MAC) ключа для каждой стороны, каждый по 16 байт, так как длина результата MD5 тоже 16 байт. К тому же RC4 использует 16 байтный ключ, который также понадобится обеим сторонам. В общем, нам понадобятся 2*16 + 2*16 = 64 байта из блока ключей

Запуская PRF, получаем:
client_write_MAC_secret = 80 B8 F6 09 51 74 EA DB 29 28 EF 6F 9A B8 81 B0
server_write_MAC_secret = 67 7C 96 7B 70 C5 BC 62 9D 1D 1F 4A A6 79 81 61
client_write_key = 32 13 2C DD 1B 39 36 40 84 4A DE E5 6C 52 46 72
server_write_key = 58 36 C4 0D 8C 7C 74 DA 6D B7 34 0A 91 B6 8F A7

Приготовтесь быть зашифрованными!

Последнее сообщение рукопожатия, отправляемое клиентом — „Финальное сообщение“. Это хитрое сообщение, которое доказывает, что никто не подделал рукопожатие и доказывает, что мы знаем ключ. Клиент берёт все байты из сообщений рукопожатия и складывает в буфер. Потом высчитываются 12 байт подтвеждения с использованием генератора псевдослучайных чисел, master key, строки „client finished“, и MD5 и SHA-1 от буфера.

verify_data = PRF(master_secret, „client finished“, MD5(handshake_messages) + SHA-1(handshake_messages))

Берём результат и добавляем в заголовок байт 0x14, указывающий на завершение, и байты длины 00 00 0с, чтобы показать, что мы отправляем 12 байт. Затем, как в будущем и для всех зашифрованных сообщений, нужно удостовериться, что расшифрованное содержимое никто не подделал. Используем MD5, а точнее его HMAC версию.

HMAC_MD5(Key, m) = MD5((Key ⊕ opad) ++ MD5((Key ⊕ ipad) ++ m)
(⊕ означает XOR, ++ означает конкатенацию, „opad“ это байты „5c 5c… 5c“, и „ipad“ это байты „36 36… 36“).

В общем, мы высчитываем:
HMAC_MD5(client_write_MAC_secret, seq_num + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment));

Как вы могли заметить, мы подмешиваем номер запроса, который защищает от специфической атаки с повторением пакета.
Осталось только зашифровать.

RC4 Шифрование


Выбранный набор алгоритмов шифрования говорит нам использовать RC4. Он настолько прост, что вы можете выучить его за пару минут.

RC4 начинается с создания 256 байтного массива S и заполнением его значениями от 0 до 255. Затем нужно пройти по массиву „вмешивая“ байты ключа. Это делается для создания автомата состояний, используемого для генерирования случайных байт. Затем мы перемешиваем массив S.

Графически это можно представить так:



Чтобы зашифровать байт, мы XORим псевдослучайный байт с байтом, который надо зашифровать.
Итак, всё довольно просто, и быстро работает. Мне кажется, из-за этого Amazon выбрал этот алгоритм.

Вспомним, что у нас есть „client_write_key“ и „server_write_key“. Это значит, что нам нужно два экземпляра RC4: один для расшифровки ответов, другой — для шифрования запросов.

Первые несколько случайных байт из „client_write“ это „7E 20 7A 4D FE FB 78 A7 33 ...“. Если поXORить эти байты с незашифрованным заголовком и проверить байты сообщения „14 00 00 0C 98 F0 AE CB C4 ...“, то получим то, что можно видеть на скриншоте Wireshark ниже:



Сервер делает почти то же самое. Он посылает „Change Cipher Spec“, а затем „финальное“ сообщение, которое включает все сообщения рукопожатия и незашифрованное „финальное“ сообщение. Это доказывает клиенту, что сервер смог расшифровать его сообщения.

Добро пожаловать на прикладной уровень!


Сейчас, через 220 миллисекунд (три часа спустя — прим. перев.), мы наконец готовы использовать прикладной уровень. Теперь можно обмениваться обычным HTTP траффиком, который будет зашифрован TLS с применением RC4 и проверен на случай подмены.

Сейчас рукопожатие завершено. Содержимое записи TLS теперь 0x17. Шифрованый траффик начинается с 17 03 01, что указывает на тип записи и версию TLS.

Шифрование пакета:

GET /gp/cart/view.html/ref=pd_luc_mri HTTP/1.1
Host: www.amazon.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.10) Gecko/2009060911 Minefield/3.0.10 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive


даст примерно следующий результат:



Сервер делает то же самое. Расшифровка даёт нам следующее:



HTTP/1.1 200 OK
Date: Wed, 10 Jun 2009 01:09:30 GMT
Server: Server

Conection: close
Transfer-Encoding: chunked

Соединение остаётся открытым до тех пор, пока любая сторона не отправит сообщение, предупреждающее о завершении, а затем закроет соединение. Если мы переподключимся незадолго после закрытия предыдущего соединения, мы можем использовать старые ключи чтобы не проводить процедуру рукопожатия заново.

Важно понимать, что на прикладном уровне может быть абсолютно что угодно. Есть множество других основанных на TCP/IP протоколов, которые могут работать поверх TLS. Например, FTPS. Всегда лучше использовать TLS вместо изобретения своего велосипеда.

На этом всё!


TLS RFC покрывает множество деталей, которые мы не обсудили. Мы рассмотрели лишь 220 миллисекундный танец между Firefox и Amazon. Узнали, что если кто-то разложит число n Amazon в p и q, то сможет расшифровать весь траффик Amazon, пока тот не сменит сертификат.

Всего за 220 миллисекунд две точки в Интернете соединились, предоставили друг другу достаточно данных для доверия, настроили алгоритмы шифрования и начали обмениваться зашифрованным траффиком.

И всё для того, чтобы Боб мог купить молочка.
Перевод: Jeff Moser
Константин Богданов @thevar1able
карма
84,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (35)

  • +17
    Спасибо за перевод интересной статьи.

    P.S. Некоторые люди все же читают теги :)
    • +38
      Теперь их прочитают все :-)
    • –10
      Имени Боб в России, как бы, нет ;)
      • +3
        Если не ошибаюсь, в России для таких примеров используют Бориса :)
        Боб — негласный общепринятый мировой стандарт)
        • –13
          Пруф в студию.
          • +9
            • –12
              Какое имеет отношение к русскому имени?
              • +2
                На счет Бориса сходу сложно вспомнить книгу российского автора. Но даже погуглив чутка, натыкаюсь на таких участников протоколов, как Антон и Борис, Анна и Борис. Если вспомню конкретную книгу (вроде бы видел в каком-то учебнике Молдовяна Н.А.), то дам знать.
                • 0
                  Фонетический алфавит же.
                  • 0
                    Если имеется ввиду метапеременные, то согласен)
        • 0
          Может Дима и Вова?
      • НЛО прилетело и опубликовало эту надпись здесь
      • +3
        Предлагаете Алису и Боба называть Чук и Гек?
      • +1
        Разумеется нет. Полностью SSL handshake за 220 мс мог пройти только где-нибудь в Калифорнии, с местным же сервером, но никак не в России.
    • +23
      > На этом всё!

      А дальше началось самое интересное.

      Где-то глубоко, в самых глубинах оперативной памяти впыхнул бит, потом еще один и еще. Это просыпались тулбары. Почувствовав вкусную добычу они ломанулись парсить содержимое страницы: «что, что же ему нужно?» — бешено полыхало в их электронных мозгах. «Может он хочет купить слона?» — думал яндекс.бар. Через несколько миллисекунд его анализатор изображений завершил работу и выдал результат: пользователь ищет слона! Вновь полетели биты по проводам — тулбар докладывал в контору, что Бобу срочно нужен слон. Через несколько секунд главный сервер директа уже обладал всей необходимой информацией и подобрал десятки объявлений о продаже слонов всех пород и расцветок. Теперь на всех сайтах Боб увидит желанное объявление, к которому он стремился всю жизнь. Слоны будут окружать его повсюду. С чувством глубокого удовлетворения Яндекс.бар засыпал, он выполнил свою работу, он сделал еще одного человека счастливым.

      Боб ненавидел слонов, с тех самых пор, как в далеком детстве в зоопарке, большой африканский слон спер у него, у маленького мальчика, мороженное, которое он купил вместо школьного завтрака. Почему-то именно тогда он захотел стать программистом баз данных. На экране компьютера была книга по PostgreSQL.

      Боб сделал заказ. Открылось окно подтверждения платежа.

      В глубина компьютера что-то снова проснулось.
    • +1
      наблюдение: первый комментатор всегда читает теги.
  • +2
    >>Четыре байта Unix time и 28 случайных байт.

    А что произойдет c этими 4 байтами 19 января 2038 года с 03:14:08?
    • 0
      Возможно, подправят код, и будет 5 байт юникстайм и 27 байт рандома.
    • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Ничего страшного — они тут нужны как дополнительная гарантия уникальности сообщений, никто их не сравнивает — а значит, и проблема знака отсутствует.

      Есть также проблема возможного повтора, но, во-первых, она наступит на 40 лет позже, а во-вторых, за полную Unix-эпоху либо алгоритмы шифрования сменятся, либо ключевая пара сервера, либо сайт исчезнет. Не говоря уже об остальных 28ми байтах.
  • +2
    Сертификат Амазона уже давно просрочен, а браузер до сих пор говорит «Всё ок». Да и RC4 уже взломали. Как же быстро время летит.
  • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    так и не понял, что за модуль — прим. перев.

    модуль n же.
  • +3
    Вы выбираете два простых числа, p и q. Умножаете их и получаете n. Далее, вы выбираете простую публичную экспоненту e, которая будет шифрующей экспонентой, и специально подобранную обратную e, d, которая будет дешифрующей. Затем вы делаете n и e публичными и храните d в секрете. Про p и q можно забыть, или же хранить вместе с d.

    Как мы уже убедились ранее, d получается из факторизации n обратно к p и q, что довольно-таки сложно.


    Если быть точным, то пропущен немаловажный для RSA шаг (ну или 2):
    1) выбираем 2 достаточно больших, примерно одного размера простых числа p и q.
    2) перемножаем их, получаем n.
    3) вычисляем функцию Эйлера для числа n, которая будет равна: Φ(n) = (p-1)(q-1), так как p и q — простые числа.
    4) выбираем открытый ключ для шифрования e, который меньше Φ(n).
    5) находим секретный ключ d для расшифрования, как обратный элемент e по модулю Φ(n), т.е. d = e^-1 (mod Φ(n)).

    6) теперь можно забыть p,q, Φ(n), у нас есть все для дальнейшей работы.
  • 0
    Эх, напомнило курс «Введение в криптографию»! Интересные были темы…
    А квантовые протоколы вообще где нибудь используются в быту?
    • 0
      На сколько знаю, сейчас это только лабораторный эксперимент. До бытового использования квантовых протоколов еще очень далеко.
  • +1
    Спасибо за статью. Узнал, что домен тоже передаётся незашифрованным. Раньше думал, что только IP можно узнать, если есть возможность сниффать трафик.
    • 0
      Если я правильно понял, то ж только если SNI на сервере и клиенте поддерживается, что (как минимум в теории) не всегда верно.
  • 0
    А при условии, что все пакеты такого общения перехвачены, расшифровать получится?
    • 0
      Нет, расшифровать имея только записанные пакеты не получится. Зато, если не использовался обмен ключами по DH (почти не применяется [1], [2] кроме google и cloudflare; см Perfect forward secrecy), и будет доступен секретный ключ сертификата — расшифровать возможно. + см VVV комментарий от alexbers.
      • +1
        Часто компании избегают обычного DH из-за того, что он требует значительных вычислительных ресурсов со стороны сервера для того, чтобы сгенерировать начальные параметры DH при установке соединения. В этом смысле ECDH лучше. Например, на серверах google и facebook DH явно выключен, а ECDH — используется.
  • +11
    Эта статья хорошо сэкономила бы мне время две недели назад, когда я заинтересовался этой темой настолько, что написал «игрушечного» tls — клиента на Питоне, чтобы ответить на множество возникших у меня при чтении спецификаций вопросов «А что если...?». В rfc было недостаточно информации, поэтому пришлось много читать исходники openssl.

    Написанный код доступен под свободной лицензией MIT по адресу github.com/alexbers/manual-tls. Он делает всё то, о чём написано в статье, выводя на экран детальный лог действий, только обмен ключами производится с помощью алгоритма Диффи-Хэллмана. Почему именно этот алгоритм?
    1) Он мало где реализован в игрушечных реализациях ssl.
    2) Он обеспечивает Perfect forward secrecy, «совершенную прямую секретность». Это значит, что если закрытый ключ с вашего сервера утечёт, например, его достанут ФБР, полиция или хакеры, то содержимое предыдущих записанных tls-сессий расшифровать все равно не получится. Ещё таким свойством обладает Elliptic curve Diffie–Hellman, который использует эллиптические кривые, нынче так модные на хабре.

    Ещё реализации ssl/tls на Питоне:
    — Toytls: github.com/bjornedstrom/toytls
    — Tlslite: trevp.net/tlslite/

    Бесплатный сервис, выводящий информацию о настройках https на узле и о возможных слабостях настройки:
    www.ssllabs.com/ssltest/index.html

    Самое полное, из встретившихся мне описаний современных атак на https, собранных в одном англоязычном документе(BEAST, CRIME, BREACH, LUCKY 13, слабости RC4 и.т.д):
    www.isecpartners.com/media/106031/ssl_attacks_survey.pdf

    P.S. спасибо thevar1able за приглашение
    • 0
      Ух ты! Очень здорово. Не хотите статью написать? :)
      • +2
        У меня есть идея статьи про использование tls для защищённой коммуникации между людьми(в простонародии — крипточат).

        Такая тема появилась потому, что во всех продуктах, которые я видел, возникает проблема доверия — я должен доверять их разработчикам. Даже если всё шифрование происходит в браузере javascript'ом и его код трижды проверен, то я не могу быть уверен, что к автору сервера не пришли и, скажем, не попросили отдавать мне особый javascript-код(см., например странную историю про LavaBit).

        К тому же в коде этих продуктов могут быть ошибки. Возьмем, например, сервис, первый по ссылке гугла по запросам «secure chat» и «crypto chat», который называется Cryptocat. Примерно два месяца назад в коде обнаружилась ошибка — из-за ошибки в реализации генератора случайных чисел групповые сообщения, которые передавались в период с 17 октября 2011 года по 15 июня 2013 года стало возможно расшифровать, см. Decryptocat. Причём в начале 2013 года проводился аудит кода компанией Veracode, который присудил ей «Security Quality Score of 100/100».

        Моя идея состоит в том, чтобы не писать совсем никакого кода, а использовать только библиотеку openssl. Собеседники должны доверять только друг другу и библиотеке openssl.

        Небольшой спойлер, о том, как можно этого достичь. Один человек выполняет команду:
        openssl s_server -nocert -cipher ADH-AES256-SHA

        а другой:
        openssl s_client -connect host:4433 -cipher ADH-AES256-SHA

        Но у такого решения есть две проблемы:
        1) Что делать, если оба человека за NAT'ом?
        2) Оно не защищает от атаки «человек посередине».

        И ещё одна маленькая, но сложная для решения проблема:
        1) Даже если данные нельзя расшифровать, доступна «метаинформация» о соединении: кто с кем соединялся, когда и сколько данных передано.

        Сейчас из всех способов их решения я пытаюсь найти лучший, если результаты меня устроят — напишу статью.
    • +1
      Вообще говоря, удивительно, но в Интернете действительно мало такой информации по HTTPS, и вообще SSL/TLS, которая бы позволяла первоначально разобраться в теме. Такое ощущение, что почти любому, кто начинает этим интересоваться (и/или использовать в работе), приходится сначала пообщаться на эту тему со знающими друзьями или коллегами, и только потом уже переходить к чтению документации, RFC и прочего.

      HTTPS широко используется для защиты информации от перехвата, а также, как правило, обеспечивает защиту от атак вида man-in-the-middle — в том случае, если сертификат проверяется на клиенте, и при этом приватный ключ сертификата не был скомпрометирован, пользователь не подтверждал использование неподписанного сертификата, и на компьютере пользователя не были внедрены сертификаты центра сертификации злоумышленника.

      Если бы хотя бы что-то подобное писали, рассказывая про HTTPS (но, конечно, с бо́льшим количеством подробностей и с необходимыми уточнениями), людям было бы уже намного проще разобраться, мне кажется.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.