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

После просмотра видео YouTube на Diffie-Hellman Key Exchange я захотел попробовать реализацию на 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 ]

16 голосов
/ 09 мая 2013

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

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

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

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

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

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

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

2.a:

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

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

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

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

2.b:

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

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

8 голосов
/ 23 марта 2012

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

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

0 голосов
/ 24 января 2014

Если вы хотите обойти сертификат SSL и man in middle, вы можете использовать цепочку биткойнов.(Или блокчейн 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
...