Шифрование на стороне клиента через 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: общение

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

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

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

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

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

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


person iRyanBell    schedule 23.03.2012    source источник


Ответы (3)


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

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

person josh3736    schedule 23.03.2012
comment
Хммм. Предполагая, что я смогу запустить javascript на клиентском компьютере с уверенностью, что он не был изменен (возможно, невыполнимая задача), будет ли это менее небезопасно? Я не думаю, что изменения данных (исключая первоначальную доставку апплета) поставят его под угрозу. - person iRyanBell; 23.03.2012
comment
Фактически, единственный способ доставить JS клиенту надежным способом - это использовать SSL. И поскольку ваше соединение уже защищено, какой смысл использовать собственную криптовалюту на этом этапе? - person josh3736; 23.03.2012
comment
Атаки повторного согласования: openssl.org/news/secadv_20091111.txt, lwn.net/Articles/362234 Атаки на более раннюю версию шифра: openssl.org/news/secadv_20101202.txt, wroot.org/posts/preventing-your-servers-from-downgrade-attacks - person jas-; 14.10.2012
comment
@ josh3736, дело может быть в хостинг-защищенном хостинге (ajaxpatterns.org/Host-Proof_Hosting) для пример. Этакий сейф, вроде менеджера паролей. Но это может не иметь отношения к описанному выше случаю. - person Alen Siljak; 23.10.2012
comment
Он никогда ничего не говорил о том, что его работа основана на браузере. Он специально сказал, что пишет это в node.js. Даже если бы он этого не сделал, его можно было бы использовать в ряде других мест и автономных приложений. Игнорировать его вопрос и просто говорить ему, что это совершенно небезопасно, очень непродуктивно. - person michaelday; 12.01.2014
comment
Это довольно неконструктивный ответ, и его не следует принимать. Проблема происхождения исходного кода ортогональна любым возможным проблемам, связанным с написанием DH на JS. Этот ответ представляет собой хрестоматийный пример увольнения посредников: news.ycombinator.com/item?id=4693920. Достаточно язвителен, чтобы получать положительные голоса, но ничего не добавляет к обсуждению. - person Jehan; 15.01.2015
comment
-1 ужасный и язвительный ответ. Описанная схема является значительным улучшением по сравнению с обычным протоколом HTTP, поскольку для ее успешной атаки требуется активная атака типа «человек посередине». Другими словами, это возможно только в том случае, если какой-то маршрутизатор по пути скомпрометирован. Да, не идеально, но не совсем часто - например, когда в последний раз вы сталкивались с поддельными DNS-ответами? Вопрос заслуживает правильного ответа. - person user541686; 21.08.2017

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

Давайте разделим контрольный вопрос на две части.

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

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

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

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

Теперь к вопросу (2). Здесь есть две проблемы. (a) Diffie-Hellman не предназначен для обеспечения того типа безопасности, который вам, вероятно, нужен; и (б) я не думаю, что вы правильно реализовали DH.

2.a:

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

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

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

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

2.b:

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

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

person Jeffrey Goldberg    schedule 09.05.2013
comment
На самом деле я думал, что DH через HTTPS / TLS может работать довольно хорошо ... Меня беспокоят потенциально поврежденные центры сертификации, и что объединение DH с аутентифицированным каналом может быть как минимум интересным ... спасибо за ваш совет по модулю / ключу длины, хотя меня больше беспокоит то, сколько времени может потребоваться браузеру для вычисления общего секрета (скажем, на обычном смартфоне) в JS. - person Tracker1; 09.09.2013
comment
@ Tracker1, когда мы говорим о безопасности, есть только два пути: относиться к этому серьезно или даже не рассматривать. Если перед запуском данных стоит подождать целую минуту или даже больше, то пользователь будет жаловаться, ругаться и ругаться, но будет ждать, в противном случае используйте что-нибудь сверхлегкое, чтобы не подпускать самых ленивых хакеров, потому что это не стоит усилий ни с одной стороны, в том числе с хакерской. Имейте в виду, что любая промежуточная альтернатива, скорее всего, небезопасна. Приложение моего банка работает медленно, потребляет память и плохо настраивается, но я доволен им, потому что это безопаснее, чем идти в банк. - person Cyberknight; 04.04.2020
comment
@Cyberknight это не вопрос того, сколько времени это займет ... вопрос в том, действительно ли он работает или нет ... если он убивает браузер, значит, он не работает. - person Tracker1; 09.04.2020

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

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

Есть две пары открытого / закрытого ключей:

CERTpublic CERTprivate

КЛИЕНТПубличный КЛИЕНТЧастный

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

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
person forestj    schedule 24.01.2014
comment
Думаю, я что-то здесь упустил. На первом этапе Клиент должен получить CERTpublic из цепочки блоков биткойнов. Разве это не с сервера? Каким образом Клиент будет уверен, что CERTpublic был получен из цепочки блоков биткойнов, а не от посредника, выдающего себя за него? - person Cyberknight; 05.04.2020
comment
Потому что биткойн - это решение проблемы византийских генералов. Другими словами, клиент может определить, что полученный сертификат является законным, из-за того, как работает биткойн. Это похоже на способ, которым биткойн-клиент может определить, был ли платеж законным. Фактически именно этот вариант использования был реализован в Namecoin. Я писал об этом здесь: sequenceread.com / - person forestj; 06.04.2020