Хранить в тайне, хранить в безопасности

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

Стойкость защиты бОльшого объема данных, известного как «открытый текст» ( plaintext ), от перехвата или модификации атакующим, зависит от безопасности меньшего объема данных, известного под названием «ключа» (*).

Таким образом, современная криптография, по сути, является разновидностью выигрыша в силе, применяемой в физике. С помощью системы передач или рычага вы можете преобразовать малое движение в большое. С помощью хорошей криптографической системы вы можете преобразовать безопасность файла-ключа, размером в 1 Кб в безопасность 10 Мб файла открытого текста. Криптосистемы не создают безопасность, они всего лишь являются рычагом, преобразовывающим движение из одной формы в другую. Криптосистемы преобразовывают безопасность малого (ключа) в безопасность чего-то бОльшего (открытого текста).

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

До 70-х годов прошлого столетия все криптосистемы были системами с общим ключом. Т.е. если Алиса хочет послать сообщение Бобу через небезопасный канал, который прослушиваются злоумышленниками, в надежде прочитать или модифицировать сообщение, тогда Алиса и Боб должны вначале каким-то образом передать общий ключ по безопасному каналу. После того, как у Алисы и Боба есть общий ключ, Алиса может зашифровать сообщение общим ключом, отправить сообщение через небезопасный канал, а затем Боб расшифрует это сообщение тем же ключом. Таким образом. Боб получит открытый текст, а злоумышленник получит только зашифрованное сообщение. (В системах с общим ключом существуют дополнительные способы проверок, чтобы Боб мог удостовериться, что никто не попытался изменить зашифрованное сообщение в процессе его передачи по незащищенному каналу.)

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

Можно подумать, а зачем Алисе и Бобу вообще нужна дополнительная криптосистема, если мы отталкиваемся от предположения, что и так существует безопасный канал для обмена ключами. Почему бы не использовать этот же безопасный канал для передачи незашифрованного текста? Суть заключается в том, что безопасный канал может быть невероятно дорогим, или может быть доступен в ограниченные промежутки времени. Например, «безопасным каналом» может служить встреча в кафе Алисы и Боба в Сиэтле в тайном подземном бункере, где они обменяются секретными ключами, а затем Алиса отправится в Швейцарию, а Боб – на Каймановы Острова, и они больше не смогут спокойно встретиться за чашкой кофе. Но после обмена ключами, они смогут обмениваться информацией безопасным образом, даже если они и не будут находиться в одной комнате.

Кроме того, безопасность системы также зависит от того, насколько Алиса и Боб смогут держать свои ключи в секрете. Если ключ Алисы или Боба станет доступным третьим лицам, например, Еве, тогда злоумышленник в лице Евы, сможет читать исходные сообщения, отправленное по небезопасному каналу. Хуже того, если ключ станет доступен Меллори и она изменит исходное сообщение, тогда она не только сможет прочитать зашифрованное сообщение, но и модифицировать его, зашифровать его обратно с помощью секретного ключа и отправить поддельное сообщение Алисе или Бобу, якобы от их лица.

А как насчет криптосистем с открытым ключом? Решают ли они эту проблему? Как выясняется, нет. Теперь появляется проблема управления четырьмя ключами. Давайте я объясню подробнее.

В основе криптосистем с открытым ключом лежит идея, что ключ не один, а два. Один – закрытый ключ, хранится в секрете. Другой – открытый, который, как несложно догадаться, является публичным. Сообщение, закодированное с помощью открытого ключа, не может быть расшифровано с помощью открытого ключа, но может быть расшифровано с помощью закрытого ключа, и наоборот. У Алисы и Боба есть пара ключей; они не знают закрытых ключей друг друга, но они знают открытые ключи. Для отправки сообщения Бобу, Алиса шифрует его с помощью своего закрытого ключа (**), и затем шифрует его с помощью открытого ключа Боба. Затем она отправляет дважды зашифрованное сообщение по незащищенному каналу Бобу. Боб затем расшифровывает это сообщение с помощью своего закрытого ключа, а затем с помощью открытого ключа Алисы. Теперь он знает, что только он может прочитать это сообщение, поскольку только у него есть свой закрытый ключ. И он знает, что сообщение не было изменено, поскольку только открытый ключ Алисы мог расшифровать это сообщение. Поэтому сообщение точно не было прочитано Евой и не было изменено Меллори.

Как я уже сказал, теперь у нас есть задача управления четырьмя ключами, хотя до этого нужно было управлять только одним. До этого, Алисе и Бобу нужно было обменяться лишь их закрытым ключом и затем хранить его в тайне. Теперь, Алиса и Боб должны хранить в секрете свои закрытые ключи. Если Ева получит закрытый ключ Боба, тогда она сможет читать любые сообщение, отправленные от Алисы Бобу. А если Меллори получит закрытый ключ Алисы, тогда она сможет отправлять поддельные сообщения Бобу, как будто они отправлены от Алисы.

С первыми двумя ключами мы разобрались; а откуда взялись еще два ключа? Я очень сильно упростил самую важную часть системы! Безопасность всей системы заключается в следующей фразе: «но они знают открытые ключи друг друга». Боб и Алиса должны каким-то образом безопасно обменяться открытыми ключами. Но зачем?

Давайте предположим, что Алиса и Боб отправляют открытые ключи друг другу. Как им это сделать? Если они будут отправлять ключи по небезопасному каналу, то не важно, сможет ли Ева прочитать их. В конце концов, они являются открытыми. Но проблема заключается в том, что Меллори может модифицировать их в процессе передачи! При передаче открытого ключа от Алисы Бобу по небезопасному каналу данных, Меллори может перехватить сообщение и заменить открытый ключ Алисы своим. Теперь Меллори знает открытый ключ Алисы и Боб думает, что Меллори – это Алиса! Когда Алиса отправляет сообщение Бобу, Меллори может его перехватить и заменить его другим сообщением, зашифрованным закрытым ключом Меллори и открытым ключом Боба. Боб расшифрует сообщение своим закрытым ключом и открытым ключом Меллори, полагая, что это открытый ключ Алисы.

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

Таким образом, для обмена открытыми ключами нужен безопасный канал. Помните, что главной целью криптографии является преобразование безопасности ключа в безопасность данных. Если ключи небезопасны, либо из-за того, что скомпрометированы закрытые ключи, или открытые ключи не связаны с их реальными владельцами, обмен данными не является безопасным.

И это не теоретическая проблема; мы должны справиться с ней в реальной жизни. Когда вы заходите на веб-сайт, и собираетесь ввести данные своей кредитной карты, вам нужны гарантии. Во-первых, вы хотите, чтобы во время передачи номера кредитной карты, никто его не перехватил. И, во-вторых, во время передачи этих данных на веб-сайт, вы хотите быть уверенными в том, что вы действительно взаимодействуете с настоящим веб-сайтом, а не с подделкой, которая выглядит аналогичным образом. Вы можете не знать открытый ключ этого сайта! Не имея безопасного механизма получения открытого ключа, вы можете получить открытый ключ злоумышленника.

На практике эта проблема решается следующим образом: клиент (вы) и сервер (веб-сайт) договариваются о доверенной третьей стороне, которая называется Сертифицирующим Органом (CA – Certitying Authority). Когда веб-сайт отправляет вам сертификат, содержащий его имя и открытый ключ, сертификат шифруется открытым ключом сертифицирующего органа. Путем расшифровки этого сообщения с помощью открытого ключа CA, вы проверяете, что сертифицирующий орган ручается за то, что этот веб-сайт действительно обладает этим открытым ключом. Конечно же, если вы не доверяете сертифицирующему органу, или если этот веб-сайт не получил сертификат у этого органа, тогда обмен ключами завершается с ошибкой, которая показывается в окне браузера, в которой говорится, что сертификат не проверен.

Но погодите-ка минутку. Но теперь мы получаем проблему управления еще одним ключом. Сертифицирующий орган должен хранить в секрете свой закрытый ключ, и каким-то образом сообщить свой открытый ключ, при этом он не должен быть перехвачен и изменен злоумышленником, который затем прикинется сертификационным органом! Мы, кажется, не решили проблему, а перенесли ее на другой уровень. Как же мы можем решить эту проблему раз и навсегда? С помощью дополнительной криптографии?

Нет. В этом месте криптография заканчивается (***). Она должна где-то закончиться; повторюсь, что суть криптографии заключается в преобразовании безопасности малого в безопасность бОльшего; эта исходная безопасность должна как-то появиться, аналогично тому, как и усилие, приложенное рычагу должно появляться извне самого рычага. Безопасная передача открытого ключа сертификационного органа является тем кусочком, которые реализуется без участия криптографии. Как вы этого добьетесь – решать вам; операционная система обычно поставляется с предустановленным списком известных открытых ключей сертификационных органов, проверенных поставщиком операционной системы. Дополнительные «корневые» сертификаты могут быть установлены системным администратором. Корневые сертификаты являются тем органом, который принимает важные решения, связанные с безопасностью от вашего имени.

Я немного отклонился от моей изначальной мысли, но я думаю, что вы меня поняли: самая сложная часть проектирования безопасности приложения на основе криптографии не связана с математикой. При добавлении криптографии в приложение, вы не должны задавать себе вопрос: «что мне нужно для шифрования открытого текста?» Главный вопрос состоит в следующем: «каким образом мои пользователи будут генерировать ключи, безопасно обмениваться секретными ключами или открытыми ключами, и обеспечивать безопасность закрытых ключей? » Безопасность всей системы основана на возможности преобразования безопасности ключей в безопасные сообщения, так что решите вначале задачу управления ключами.

------------------------

(*) Строгость и слабость криптосистемы зависит от возможности выполнения ею своей основной цели. Если безопасность сообщения может быть раскрыта без раскрытия безопасности ключа, то система считается слабой. Целью современной криптографии является создание надежных криптосистем.

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

(***) Для полноты описания следует сказать, что протокол HTTPS основан на безопасном обмене ключей уровня сессии между клиентом и сервером. Затем общий ключ используется для шифрования сообщений, передаваемых между ними. Как мы уже сказали, для обмена общим ключом требуется безопасный канал. Для создания канала клиент и сервер договариваются об органе сертификации, которому они оба доверяют. Сервер уверяет клиента в том, что сертифицирующий орган ручается за открытый ключ сервера. Затем для оставшейся части сессии клиент предлагает общий ключ, шифрует его открытым ключом сервера и отправляет его ему. Итак, безопасный обмен общим ключом сессии основан на: (1) секретности закрытого ключа сервера, (2) секретности закрытого ключа сертификационного органа и (3) наличия у клиента и сервера точной копии открытого ключа сертификационного органа, полученного по безопасному каналу, защищенному не криптографией. Криптосистема использует секретность двух закрытых ключей и успешный обмен одним открытым ключом в безопасность сообщений, передаваемых внутри сессии. Если один из этих ключей будет скомпрометирован, тогда вся безопасность этой системы развалится на части. (Для этого сертификационные органы также публикуют «список отзывов сертификатов» (revocation list) серверов, чьи закрытые ключи скомпрометированы, чтобы вы могли знать, кому нельзя доверять).

Оригинал статьи