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

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

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

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

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

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

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

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

  • Шаг 2: Связь

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

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

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

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

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

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

3 ответов


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

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


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

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

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

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

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

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

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

2.a:

Diffie-Hellman Key exchange, когда все сделано правильно, безопасен для обмена ключами, но ничего не делает для аутентификации. Вот почему вопрос" Безопасно ли это " часто является неправильным вопросом. Это безопасно для некоторых целей, но массово небезопасно для других, поскольку он не предназначен для этих других целей.

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

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

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

2.b:

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

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


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

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

существует две пары открытого и закрытого ключей:

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