📅 2023-12-30 📄 source
Заметки про криптографию, которые я начал писать, вникая в криптографические задачи в связи с работой, разросшиеся до полноценного объяснения. Частичный перевод на русский
Переведена только первая часть. Остальное едва ли нужно людям, не знающим английского
Первая часть довольно базовая и написана в основном для того, чтоб рассказать друзьям, чем я занимаюсь.
Если сразу хочется задать вопрос "что из того, с чем я сталкиваюсь повседневно, это поможет понять?" - см. абзац про HTTPS, можно использовать его как альтернативную "точку входа" в текст и попробовать читать снизу вверх.
Все сколь-нибудь разумные люди, выросшие с компьютерами, имеют общее интуитивное представление о криптографии как о чем-то, у чего есть "ключи" (являющиеся, как и все в компьютере, числами, представленными байтами), "шифрование", которое является преобразованием информации во что-то "нечитаемое", и "дешифрование", являющееся обратным процессом. Некоторые менее очевидные важные свойства современных криптосистем:
"Идеальным" решением для исключения корреляции было бы складывать каждый символ данных с символом случайной последовательности, фактически превращая данные в "случайный шум"; криптосистема, в которой "ключом" является (одноразовая) случайная последовательность такой же длины, как и данные, является действительно абсолютно невзламываемой, но практически непригодной для использования (шпионские "одноразовые шифроблокноты"); в криптосистемах с хорошим балансом между защищенностью и практичностью ключи имеют фиксированную длину (короткую, но достаточную, чтобы сделать взлом перебором практически невозможным) и случайные значения, и работу такой криптосистемы можно рассматривать как "растягивание" энтропии ключа на длину данных
Об устойчивости современных криптосистем ко взлому перебором: при длине ключа 256 бит, ключ может иметь 2**256=115792089237316195423570985008687907853269984665640564039457584007913129639936 разных значений; с нынешними скоростями памяти только на то, чтоб записать в память все возможные значения ключа, потребовалось бы (2**256)*8/30000000000/3600/24/365=9.791314834882142e+59 (10^59) лет (предположительный возраст Вселенной 1.37e+10 лет)
TODO with asymmetric crypto only used for signing in modern applications, it may be better to present it as signing tool, instead of starting with encryption and slowly crawling to signing and auth
TODO language unification: crypto system/mechanism/algorithm/method, communication/connection/channel, etc.
Симметричная и асимметричная криптография (aka криптография публичного ключа): в асимметричных криптосистемах используются "пары ключей", состоящие из "публичного ключа", используемого для зашифровывания, и связанного с ним (математически) "приватного ключа", используемого для расшифровывания (математический дизайн такой криптосистемы должен делать невозможным получение приватного ключа из публичного, т. е. расшифровку без приватного); "симметричная криптография" - это "ретроспективный" термин для не-асимметричных криптосистем, в которых используется один ключ (теперь часто называемый "симметричным ключом") и для зашифровывания, и для расшифровывания. Асимметричная криптография решает две проблемы, известные как проблема распределения ключей и аутентификация (см. ниже).
Распространенные симметричные криптосистемы: AES
Распространенные асимметричные криптосистемы: RSA, ECDSA
Проблема распределения ключей: в коммуникационной системе с X пользователями, каждый из которых желает иметь возможность общаться с любым другим (защищенно и лишь посредством этой системы), при использовании симметричной криптографии, по одному ключу должно быть создано на каждую возможную пару пользователей (X*(X-1) ключей всего, что много), и каждый такой ключ должен быть каким-то образом защищенно сообщен соответствующей паре (оставаясь секретом от остальных). С асимметричным, каждый пользователь должен сгенерировать лишь одну "пару ключей" (всего X "пар ключей"). После этого, любой пользователь может использовать "публичный ключ" другого пользователя, чтоб отправить ему зашифрованное сообщение, которое только тот сможет расшифровать с помощью своего "приватного ключа". Но:
Аутентификация (проверка подлинности): это проверка того, что кто-либо действительно является тем, за кого себя выдает. Для защищенной связи необходима возможность проверки того, что сообщение, полученное от другой стороны, было действительно отправлено той стороной и не было изменено (возможно, злонамеренно) в ходе доставки. Даже с изобретением механизмов, позволяющих сторонам договориться о шифровании посредством несекретных сообщений, остается угроза атаки "человека посередине", который связывается с обеими сторонами, притворяясь другой стороной для каждой из них, что делает такие системы не полностью защищенными в отсутствие средств аутентификации. Помимо шифрования, у асимметричной криптографии есть еще один способ применения, известный как "цифровая подпись" (см. ниже). Это позволяет изобрести сертификаты и PKI (см. ниже), которые решают проблему аутентификации
TODO what is correct to speak of as being authenticated, party or messages/data supposedly received from that party? Many resources use "authentication of party" concept, but it creates some confusion, as in communication system party never "touches" another party, only received messages
Схема Диффи-Хеллмана: алгоритм, который позволяет 2м сторонам договориться про секретное число (читай: симметричный ключ) таким образом, что его невозможно получить из перехваченных сообщений
Все алгоритмы асимметричной криптографии и DH основаны на "односторонних функциях" - математических функциях, для которых "вычислительно просто" (читай: возможно практически мгновенно) вычислить значение функции для аргумента, но "вычислительно сложно" (читай: невозможно, если не считать полного перебора, который займет вечность) вычислить исходный аргумент для известного значения функции. Довольно забавно, что ни для одной такой функции, используемой в существующих криптосистемах, нет строгого математического доказательства того, что она является истинно "односторонней функцией"; есть лишь общественный консенсус, что использовать основанные на них криптосистемы "достаточно безопасно", потому что их "обращение" "интуитивно кажется" невозможным, и никто до сих пор не опубликовал доказательство существования способа для этого, несмотря на всемирную славу и премии (хоть и не без горечи), ожидающие любого, кто сделает это; на самом деле, этот вопрос является частным случаем фундаментальной проблемы "P?NP", известной среди математиков и информатиков
Цифровая подпись: короткая, фиксированной длины информационная последовательность, полученная из данных и приватного ключа, позволяющая любому с теми же данными и соответствующим публичным ключом проверить, что она действительно получена кем-то, кто имеет приватный ключ. Сама по себе подпись позволяет аутентифицировать подписанные данные при условии, что публичный ключ уже аутентифицирован, но нужно каким-то образом аутентифицировать сам публичный ключ.
Генерация подписи обычно включает предварительный шаг хэширования для преобразования сообщения произвольной длины в короткую, фиксированной длины информационную последовательность, которая далее преобразуется в подпись с использованием приватного ключа; подпись RSA работает, по существу, как "шифрование" "message representative" (хэша подписываемого сообщения, дополненный данными, содержащими идентификатор используемой хэш-функции); стандарт RSA называет это "применением signing primitive", где "signing primitive" идентично "decryption primitive" и по сути представляет собой главный шаг алгоритма дешифрования RSA (использующего приватный ключ), с определенными пред- и постпреобразованиями
Новые стандарты асимметричных криптосистем даже не описывают процедуры шифрования/дешифрования, только подписи/верификации
Сертификат (aka сертификат публичного ключа): публичный ключ, дополненный информацией, позволяющей идентифицировать владельца "пары ключей" и аутентифицировать (т. е. удостовериться, что ключ действительно принадлежит указанному владельцу), включая
С этой дополнительной информацией и доступностью "связанного" "вышестоящего" сертификата, к которому уже есть доверие (не только в том смысле, что он содержит подлинный публичный ключ, принадлежащий "3й стороне", но и в том, что эта "3я сторона" не допустит подписи своим приватным ключом сертификата, связывающего идентификатор какой-либо стороны с публичным ключом, который принадлежит кому-то другому), то сертификат может быть валидирован, т. е. если его подпись прошла проверку, то публичный ключ в нем может считаться подлинным (созданным именно той стороной, идентификатор которой указан в сертификате как идентификатор владельца ключа, а не каким-нибудь злоумышленником, который осуществляет атаку "человек посередине", чтобы расшифровывать перехваченную информацию или подделывать подписи, притворяясь той стороной)
Да, зависимость валидации сертификата от другого сертификата создает "цикл", см. в следующих пунктах, каким образом этот "цикл" "разрывается"
Самоподписанный сертификат: сертификат, подписанный приватным ключом, соответствующим публичному ключу, который он же и содержит; т. е. он не связан ни с каким "вышестоящим" "удостоверяющим" сертификатом
Корневой сертификат: самоподписанный сертификат, который выдан "пользующимся всеобщим доверием удостоверяющим центром", распространяемый в составе программ, прошивок устройств и т. д., которые изначально сконфигурированы так, что "считают" этот сертификат "доверенным удостоверяющим"
CA (Certification Authority): "пользующиеся всеобщим доверием удостоверяющие центры", которые подписывают (выпускают) сертификаты и предоставляют корневые сертификаты для валидации подписанных ими; доверие к ним основано на публичности ключевых фигур, отсутствии доказанных обвинений в подписывании "поддельных" сертификатов или утечке приватных ключей, и их заинтересованности в сохранении "чистой" репутации (поскольку она позволяет им зарабатывать, посредством взимания оплаты за подписывание сертификатов или как-то еще)
Есть средства минимизации негативных последствий инцидентов, таких как подпись "поддельного" сертификата или утечка приватного ключа CA, позволяющие быстро доставить информацию о том, какие сертификаты и ключи "утратили доверие" в программное обеспечение, в целом известные как "отзыв сертификата"; большие инциденты с отзывами глобально используемых корневых сертификатов CA случались единицы раз за историю Интернета
Цепочка доверия: цепочка сертификатов, в которой каждый следующий ("вышестоящий") является "удостоверяющим" для предыдущего, так что предыдущий может быть валидирован через следующий, заканчивающаяся "корневым".
CSR (Certificate Signing Request, запрос на подписывание сертификата): сообщение в определенном формате, аналогичном самоподписанному сертификату, но предназначенном для CA, который должен подписать сертификат своим публичным ключом
TODO: explain how identity of requesting party is proven/verified by CAs
PKI (Public Key Infrastructure, инфраструктура публичного ключа): инфраструктура, состоящая из всего вышеперечисленного; можно думать об отношении понятия PKI к вышеперечисленному как об отношении Интернета к совокупности сетевых протоколов, программного и аппаратного обеспечения
После того, как сертификат стороны валидирован, данные в сообщениях, полученных (якобы) от нее могут быть аутентифицированы, если они сопровождены цифровой подписью (либо являются производными от данных, ранее отправленных этой стороне зашифрованными ее публичным ключом, либо являются производными от ранее полученных данных, которые уже были аутентифицированы, т. е. если все данные целиком являются доказательством того, что сторона владеет соответствующим приватным ключом). Но на практике по той же причине, по которой для шифрования собственно данных используется симметричная криптография, для аутентификации зашифрованных симметричной криптографией сообщений также используется другие механизмы, которые используют тот же симметричный ключ (который был "выработан" сторонами с использованием асимметричной криптографии и который также является доказательством того, что у другой стороны есть приватный ключ), в целом известные как "authenticated encryption" ("аутентифицированное шифрование")
X.509: стандарт ITU-T (International Telecommunications Union, Международного союза электросвязи) для PKI, который определяет в том числе формат сертификатов; так как конкурирующих стандартов, в сущности, нету, под PKI обычно имеется в виду именно X.509 PKI
Да, это значит, что безопасность в Интернете в основном основана на доверии к CA
На самом деле, есть как минимум одна значимая децентрализованная альтернативная PKI, "Web of trust" ("паутина доверия"), которая не требует CA, но требует определенных усилий от пользователей, пользуется некоторой популярностью в сообществе свободного ПО
Также стоит упомянуть "государственные" PKI, используемые в сервисах цифровых гос. услуг, напр. для аутентификации на государственных веб-сервисах, позволяющих осуществлять такие действия как передача прав на собственность или голосование на выборах; например, украинская "квалифицированная электронная подпись" которая основана на какой-то "доморощенной" криптосистеме с очень странными решениями; самым безумным в ней, пожалуй, является то, что большинство правительственных веб-сервисов, которые ее используют, требуют для аутентификации отправлять приватный ключ пользователя
В некоторых источниках утверждается, что аббревиатура PKI _обозначает_именно_ X.509 PKI и неприменима для обозначения других систем, решающих такие же проблемы посредством асимметричной криптографии, или же что она применима только для обозначения централизованных систем с CA, но похоже, что это не общепринятое мнение
Серверный и клиентский сертификаты: серверный сертификат - это сертификат, предназначенный для отправки сервером клиентам в процессе установления защищенного соединения; клиент может валидировать его посредством цепочки доверия и использовать публичный ключ из него для шифрования отправляемых серверу данных или аутентификации полученных от сервера данных. Клиентский сертификат - это, ну, аналогичная вещь, но с "поменянными местами" сторонами. Это разделение не про сами сертификаты, а про то, как они используются. Серверные сертификаты/аутентификация с их использованием применяются повсеместно, клиентские - в основном там, где "клиентом" является софт, работающий без взаимодействия с человеком (напр., IoT) или, обобщеннее, там, где аутентификация не требует взаимодействия с человеком (управление ключами и сертификатами требует знаний и усилий, поэтому там, где клиентами является "пользовательский софт" с использующими его "обычными людьми", обычной практикой является, после установления зашифрованного соединения между аутентифицированным сервером и неаутентифицированным пользователем, запрашивать у клиента какой-нибудь "секрет", который "проще для пользователя", но требует ручного ввода, напр., пароль; кроме того, во многих случаях сервер является просто "источником публичной информации", и необходимость проверять, кем на самом деле является клиент, просто отсутствует)
Клиентские сертификаты и аутентификация с их использованием в "пользовательском софте" используется в основном для защиты доступа к сущностям, являющимся особо значимой целью для хакеров, такими как административные интерфейсы особо значимых сервисов
TLS (Transport Layer Security, безопасность транспортного уровня) and SSL (Secure Socket Layer, уровень защищенных сокетов): распространенные протоколы для установления защищенного зашифрованного соединения поверх TCP/IP (Интернета), которые опираются на X.509 PKI в большинстве сценариев использования; TLS - современный, стандартизированный IETF, а SSL - его давно устаревший "предок", название которого все еще часто встречается "тут и там", часто как синоним. Процесс установления TLS-соединения называется "handshake" (хэндшейк, "рукопожатие"). Хэндшейк включает в себя "выработку" сторонами общего симметричного ключа и аутентификацию (посредством сертификата). Для TLS 1.3, список поддерживаемых асимметричных криптосистем для "выработки" симметричного ключа/аутентификации можно увидеть в https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.3 ; список поддерживаемых симметричных криптосистем для шифрования передаваемых данных можно увидеть в https://datatracker.ietf.org/doc/html/rfc8446#appendix-B.4
https://www.cloudflare.com/learning/ssl/what-happens-in-a-tls-handshake/
Во многих источниках утверждается, что "TLS 1.3 больше не поддерживает RSA", но на самом деле имеется в виду "RSA key exchange algorithm (алгоритм "выработки" ключа RSA)", т. е. вариант, при котором безопасность "выработки" симметричного ключа основана исключительно на RSA и требует, чтоб сообщения, которыми стороны согласовывают симметричный ключ, были зашифрованы RSA; в TLS 1.3 есть лишь "выработка" ключа посредством DH с аутентификацией с использованием сертификатов (подписывание сообщений DH, чтобы другая сторона могла аутентифицировать их посредством публичного ключа в предоставленном сертификате), и RSA все еще поддерживается для этого и остается популярным выбором при создании сертификатов
HTTPS (HTTP Secure): HTTP поверх TLS, т. е. HTTP сообщения передаются через TLS-канал
К этому моменту вы у вас должно бы образоваться понимание того, что в целом происходит, когда вы вводите в адресной строке браузера URL "https://..." и видите знакомый "зеленый замочек" после загрузки страницы... Либо ошибку установления защищенного соединения
OpenSSL: популярная криптографическая программная библиотека с открытым исходным кодом, предоставляющая реализацию TLS и необходимых для него криптографических систем/алгоритмов/механизмов/форматов/протоколов, включая X.509 PKI, используемая большинством веб-серверов Интернета; также включает в себя утилиту для генерации асимметричных "ключевых пар", сертификатов и пр. и управления ими.
Есть и другие распространенные реализации TLS, в том числе GnuTLS и NSS (используется в Firefox)
Подытожим: