TLS, клиентские сертификаты, TOFU и всё такое

Этот документ находится в процессе создания!

Введение

Gemini делает обязательным защиту соединения с помощью TLS. Кроме того, он поддерживает использование клиентских сертификатов и альтернативных схем подтверждения подлинности сертификатов, что для многих людей непривычно. Для множества потенциальных разработчиков и разработчиц Gemini это самая сложная часть из всех. Этот документ нацелен предоставить краткое введение в значимые концепции. Он не слишком детальный или точный: целью является позволить людям понять и осмыслить то, как эта штука работает на уровне абстракции поверх всех криптографических подробностей.

Но это не разбор полностью "с нуля". Этот документ предполагает, что вы знакомы с некоторыми базовыми концептами асимметричной (использующей "публичные ключи") криптотграфии; не с математическими формулами и тем, как и почему всё это работает, а с абстракцией, общей картиной происходящего. В сущности, вы должны уверенно себя чувствовать с идеями:

Основы сертификатов

Что такое сертификат TLS?

Для наших целей, вы можете думать о TLS-сертификате как о комбинации следующих вещей:

Метаданные о субъекте и эмитенте имеют одинаковую структуру. Сертификат содержит "Distinguished Name" (DN) субъекта и эмитента. DN имеет несколько полей, но самое важное из них - так называемое "Common Name" (CN). Оно не обязано являться, но в типичном реальном сценарии использования почти всегда является именем узла, например `paypal.com`.

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

Каков типичный сценарий использования TLS-сертификата?

Предположим, что вы легитимный оператор сервера `example.com`. "Нормальный" способ использовать TLS - это связаться с надёжной третьей стороной, называемой "Certificate Authority" (CA), и сказать "Привет, CA, мой DN - бла-бла-бла, и в частности мой CN - example.com. Этот набор байтов вот здесь - мой собственный публичный ключ". CA "делает что-то", чтобы убедиться, что это действительно вы, легитимный оператор example.com, и затем они используют свой приватный ключ, чтобы подписать сертификат, в которым указан ваш DN (как субъекта), их собственный DN (как эмитента), плюс период действия. Затем вы настраиваете вебсервер, почтовый сервер или ещё что-нибудь, чтобы раздавать этот сертификат, когда клиенты делают TLS-запросы к серверу.

На стороне клиента веб-браузеры и/или операционная система обычно поставляется с огромной кучей публичных ключей для распознавания предустановленных CA. Когда клиенты подключаются к вашему вебсерверу и получают ваш сертификат, они могут использовать DN вашего CA, чтобы найти публичный ключ в своей куче, а затем проверить на подлинность цифровую подпись вашего сертификата. Если подпись подлинна, это говорит им о том, что действительно конкретный добропорядочный CA сделал что-то, чтобы убедиться, что публичный ключ в этом сертификате действительно принадлежит example.com. Так как клиенты доверяют CA, они принимают за истину, что этот публичный ключ подлинный и (предполагая, что период действия не истёк) всё хорошо: клиент и сервер используют удостоверенный публичный ключ, чтобы создать защищённый канал через замысловатый процесс, который на самом деле делает с сертификатом кое-что ещё.

Почему всё это необходимо?

Предположим, что когда клиент устанавливает соединение с example.com, сервер отправляет по линии только публичный ключ вместо сертификата. Клиент всё ещё может использовать этот ключ, чтобы шифровать информацию, которую он отправляет на сервер, и эта информация будет защищена от посторонних глаз. Но есть риск того, что будет некто, кто может не просто прослушивать соединение, но и вмешиваться более активными способами - например, это может быть провайдер клиента либо сервера или кто-то, сумевший обмануть DNS-провайдера пользователя разрешать имя example.com в их собственный сервер - они могут действовать как так называемый "человек посередине" или "Man in the Middle" (MitM). Когда клиент пытается установить соединение с сервером, атакующие отправляют клиенту *их собственный* публичный ключ вместо ключа сервера. В то же самое время они подключаются к запрошенному серверу, получая настоящий публичный ключ. Атакующие используют их собственный приватный ключ, чтобы расшифровать данные, полученные от клиента, а затем снова зашифровывают их публичным ключом сервера перед отправкой данных на сервер - и наоборот в противоположном направлении. Клиент и сервер всё ещё могут общаться друг с другом, и всё кажется работающим, но атакующие могут прослушивать соединение даже несмотря на то, что клиент и сервер всё зашифровали.

Чтобы предотвратить это, клиент должен знать, что какой бы публичный ключ он ни получил по линии, он действительно принадлежит example.com, а не каким-нибудь злоумышленникам, которые перехватили соединение и подменили ключ на свой. Будьте уверены, это очень сложная проблема. Существует множество возможных решений, все со своими плюсами и минусами. Мейнстримное решение в сегодняшнем интернете - использовать сертификаты, подписанные CA. Оно по сути делегирует эту трудную задачу установления того, кто взаправду каким ключом владеет, небольшому (относительно числу компьютеров в интернете) количеству доверенных лиц (CA), от которых ожидается хорошо выполнять свою работу.

Так, если вы отдалитесь от технических подробностей того, что находится *внутри* TLS-сертификата и что делают с ними компьютеры, а вместо этого подумаете о *роли*, которую они играют, TLS-сертификаты - это способ для одной стороны (эмитент) поручиться за действительность утверждения другой стороны (заявление субъекта "этот ключ мой") таким образом, который убедит каждого, кто имеет уже существующие доверительные отношения с эмитентом (имея публичный ключ эмитента и, следовательно, имея возможность проверить его цифровую подпись).

Хорошо, то есть с системой CA проблема MitM решена?

Ну, и да и нет.

Некоторые люди не очень довольны уровнем безопасности, предоставляемым системой CA. Если только не нагромоздить дополнительных штук поверх простой процедуры подтверждения, обрисованной выше, *любой* CA, чей публичный ключ предустановлен в вашем браузере или операционной системе, может подписать сертификат для *любого* узла, и ваша система с радостью примет его. Это может быть список из буквально сотен CA, принадлежащим компаниям или государствам по всему миру, которые могут в действительности иметь сильно расходящиеся уровни доверия (в реальности, вы не слышали и не взаимодействовали ранее с большинством из них). Если ваша система будет принимать сертификаты с любого из них, вся система настолько же защищена, как и самый уязвимый CA: тот CA, который наименее тщательно проверяет утверждения о владении публичным ключом, или же CA с наихудшей интернет-безопасностью, чьи приватные ключи оказываются украдены, или же CA с наиболее подкупными сотрудниками, или же CA, чьё правительство имеет наибольшую правовую силу вынудить их подписать поддельный сертификат под угрозой тюремного заключения или ещё чего похуже. Самый уязвимый CA может быть действительно таким слабым, и если обнаружится, что некоторый CA "вышел из-под контроля", уйдёт много работы и займёт много времени удалить его публичный ключ из каждого устройства, на котором он был установлен.

Некоторые люди не так озабочены уровнем безопасности, предоставляемым системой CA, а вместо этого недовольны по политическим или философским причинам тем, что целая система основана в первую очередь на относительно небольшом количестве частных коммерческих корпораций, обслуживающих дорогую централизованную инфраструктуру и берущих с конечных пользователей деньги (иногда много денег) за сертификаты.

Что такое самовыданный и самоподписанный сертификат?

Сертификат называется "самовыданным", когда субъект и эмитент - одно и то же лицо, а "самоподписанным" - если он подписан приватным ключом, соответствующим содержащемуся в нём публичному ключу. Сертификат может быть самовыданным и при этом не самоподписанным, и наоборот, но в самом распространённом случае (в том самом, который большинство людей имеют в виду, когда говорят о "самоподписанных сертификатах") сертификат имеет оба эти свойства.

Самоподписанные сертификаты несовместимы с типичным использованием сертификатов: они не функционируют таким образом, который позволял бы заверить владение публичным ключом, потому что отсутствует третья сторона, такая как CA, которой клиент уже доверяет и которой сервер доказал свою подлинность. Любой может создать самоподписанный сертификат с таким CN, который душе угодно. Если вы используете самоподписанный сертификат для своего сервера, клиент не в состоянии отличить его от подделанного злоумышленником для MitM-атаки - как минимум не просто просмотрев сертификат и проверив подпись. В этом причина того, что самоподписанные сертификаты обычно признаются небезопасными.

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

самоподписанные сертификаты абсолютно нормально использовать.

Вы можете спросить: в чём ценность использования самоподписанных сертификатов вместо использования одних лишь публичных ключей? Ответ: фактически никакая, и существует множество безопасных протоколов, которые используют публичные ключи без сертификатов. Но TLS построен полностью вокруг концепта подписанных CA сертификатов и не предоставляет способа использовать публичные ключи отдельно. Вы можете думать о самоподписанных сертификатах как о "хаке", чтобы обойти эту систему: они позволяют использовать уже существующий стек технологий TLS, но отказаться от системы CA.

Клиентские сертификаты

Скоро появится.

TOFU

Скоро появится.

Практические вопросы

Скоро появится.

Proxied content from gemini://gemini.circumlunar.space/docs/ru/tls-tutorial.gmi

Gemini request details:

Original URL
gemini://gemini.circumlunar.space/docs/ru/tls-tutorial.gmi
Status code
20
Meta
text/gemini
Proxied by
kineto

Be advised that no attempt was made to verify the remote SSL certificate.