Клиентское шифрование по HTTP с обменом ключами Диффи-Хеллмана и AES

После просмотра видео на YouTube по обмену ключами Диффи-Хеллмана я захотел попробовать реализацию на JavaScript (закон Этвуда).

Я набросал шифр на Node.js со следующими правилами:

  • Шаг 1: Клиент и сервер согласовывают общий ключ:

    • Клиент и сервер начинаются с 512-битного открытого открытого ключа pK

    • Клиент генерирует 512-битный первичный закрытый ключ kC и отправляет powMod(3, kC, pK)

    • Сервер генерирует 512-битный первичный закрытый ключ kS и отправляет powMod(3, kS, pK)

    • Клиент и сервер используют powMod(response, privatekey, pK) в качестве общего ключа

  • Шаг 2: Общение

    • Перед тем как клиент отправляет данные, они шифруются с помощью общего ключа с использованием крипто-библиотеки Stanford Javascript (256-битная AES, аутентификация HMAC, усиление пароля PBKDF2 и аутентификация-шифрование CCM).

    • Как только сервер расшифровывает данные с помощью общего ключа, он генерирует новый 512-битный первичный закрытый ключ и отправляет его как зашифрованный ответ SJCL.

    • Клиент и сервер переключаются на новый общий ключ с помощью powMod(3, prevSharedKey, newPrivKey)

Теперь у меня есть несколько вопросов..

Насколько безопасна такая система по сравнению с HTTPS или другими алгоритмами? Каковы самые слабые стороны такой системы?

С точки зрения безопасности / практичности, было бы лучше использовать 1024-битные ключи для большей безопасности? Варианты HMAC/PBKDF2/CCM излишни? Стоит ли модулировать общий ключ? Спасибо за прочтение!

3 ответа

Решение

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

Короче говоря, без SSL вы уязвимы для атак "человек посередине". Никакая криптографическая реализация JavaScript на основе браузера не может преодолеть этот факт.

Ваша система в целом небезопасна, но я не пытаюсь отговорить вас или кого-либо от игры с подобными вещами. Вы должны продолжать. Но очень важно, чтобы вы рассматривали все, что вы создаете, как "игрушечную" систему, которая никогда не должна рассматриваться или рекламироваться как "безопасная".

Давайте разберем вопрос безопасности на две части.

  1. Насколько безопасен обмен ключами?
  2. Насколько безопасно шифрование, которое вы используете после получения общего ключа?

Позвольте мне сначала ответить на (2), так как это будет самым простым. Это будет ужасно небезопасно, если вы не будете умнее всех людей, которые работали и изучали TLS на протяжении многих лет. TLS до версии 1.2 (которую используют несколько сайтов) в принципе уязвимы для выбранных атак зашифрованного текста (CCA) и для атаки BEAST в зависимости от выбора костюма шифра. И SSL 2.0 хуже сломан.

Дело в том, что очень умные люди, работавшие над этими протоколами годами, ошиблись. Есть все основания полагать, что вы сами, работая над подобными вещами, сами совершите огромные ошибки. Основные алгоритмы шифрования в порядке. Они не сломаны. Но протоколы есть.

Так что, если вы не изучили и не полностью поняли все детали SSL, почему они существуют и как они пошли не так в некоторых случаях, то почти наверняка любой разработанный вами протокол будет ужасен.

Теперь на вопрос (2). Есть две проблемы с этим. (а) Диффи-Хеллман не предназначен для обеспечения безопасности, которая вам, вероятно, нужна; и (б) я не думаю, что вы правильно внедрили DH.

2.а:

Обмен ключами Диффи-Хеллмана, если все сделано правильно, безопасен для обмена ключами, но ничего не делает для аутентификации. Вот почему вопрос "это безопасно" часто является неправильным вопросом. Он безопасен для некоторых целей, но в целом небезопасен для других, поскольку не предназначен для этих других целей.

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

Однажды настроенный таким образом, Мэллори может действовать как Человек Посередине между Сэмом и Чарли. Когда Чарли отправляет данные, предназначенные Сэму, Мэллори расшифровывает их, используя общий ключ между C и M, читает (и, возможно, изменяет), а затем повторно шифрует общий ключ между M и S и отправляет их в S,

Чтобы решить проблему аутентификации, вам нужна какая-то инфраструктура открытых ключей (PKI), и это действительно проблема. Система Центров сертификации и такая, которая у нас есть с SSL/TLS, чревата проблемами, но она остается лучшей из существующих.

2б:

512-битный открытый модуль вместе с 512-битными закрытыми ключами недостаточно силен. Ключи DH должны быть больше. Я не пошел бы с чем-то меньшим, чем 2048 бит. Вы можете сойти с 1024 битами, вы не беспокоитесь о том, что кто-то сможет открыть сегодняшние секреты через пять лет.

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

Если вы хотите обойти SSL-сертификат и "человека в середине", вы можете использовать цепочку биткойнов. (Или блокчейн altcoin.)

Огромное предостережение: клиент должен либо загрузить, либо сохранить весь файл блокчейна.

Существует две пары открытых / закрытых ключей:

CERTpublic CERTprivate

CLIENTpublic CLIENTprivate

РЕГИСТРАЦИЯ ИМЕНИ:

Server -> CERTpublic and name_to_register -> Bitcoin Blockchain

АУТЕНТИФИЦИРОВАННОЕ СОЕДИНЕНИЕ:

Client <- CERTpublic <- Bitcoin Blockchain
Client -> CERTpublic(CLIENTpublic) -> Server or Adversary
Client <- No_response_or_incorrect <- Adversary 
Client <- CLIENTpublic(CERTprivate(content)) <- Server
Другие вопросы по тегам