[Программа] Шифрование Диффи-Хеллмана на JavaScript

  • Автор темы Алексаня Тюрик
  • Дата начала

Есть ли смысл дорабатывать программу, или есть готовые решения давно?

  • Очень интересная работа, только "ВПЕРЁД"!!!

    Голосов: 2 100,0%
  • Есть аналоги, которые давно выручают без этой программы.

    Голосов: 0 0,0%

  • Всего проголосовало
    2
Алексаня Тюрик

Алексаня Тюрик

Ч0ткий!
Мне удалось реализовать на JavaScript достаточно быструю генерацию закрытых сесионных ключей криптоалгоритма Диффи-Хеллмана (при 2048-битном модуле и 256-битной экспоненте на это требовалось около 10 секунд или менее - на настольном ПК с двухядерным 3 ГГц процессором).
-

Рабочую библиотеку функций с сопутствующими файлами я передал в общественное достояние и выложил на Гитхаб:

https://github.com/michael-hock/skrasite

Там в файле DHJS_rus.rtf - математические выкладки со всеми формулами, по которым я создавал вычислительный алгоритм, краткое описание функций и файлов. DHJS_eng.rtf - то же самое на английском языке.

DH_JS_Test.htm - файл для демонстрации возможностей: он работает и за Алису, и за Боба, которые обманиваются открытыми числами и генерят одинаковые сессионные ключи.

DH.js - самое ядро: библиотека функций, реализующих на JavaScript достаточно быстрое умножение по модулю и возведение в степень по модулю очень больших натуральных чисел.

consts*.js - файлы с предвычисленными константами, позволяющими в несколько раз ускорить вычисление (2^a) mod P.

const_gen.htm - генератор таких файлов с константами.

Пока это открытая библиотека функций.

Дальнейшее развитие проекта SkraSite мне видится в создании мессенджера, для которого не надо будет специальной программы на клиенте (как для Telegram и WhatsApp), а будет достаточно любого браузера. А серверная часть - PHP-файл, который можно "подкинуть" на любой веб-сайт на хостинге с поддержкой PHP. В отличие от JS, в ядре современного PHP уже есть встроенная математика больших чисел, на сервере с этим будет проще.

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

Протокол Диффи-Хеллмана, в отличие от RSA, обеспечивает forward secrecy. Если на RSA кому-то удастся похитить или подобрать закрытый ключ - им можно расшифровать сессионные ключи в перехваченном трафике, а сессиоными ключами - и само содержимое сообщений. На DH такое не получится, поскольку никаких постоянных закрытых ключей нет, а сесионные не пересылаются даже в зашифрованном виде и окончательно уничтожаются по завершению сессий.

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

Если у меня дальше не получится - надеюсь, другим программистам эта библиотека функций будет полезна.

Источник (через TOR): lwplxb6ushy6x3yr.onion/viewtopic.php?id=10301
 
Последнее редактирование модератором:
F

fxkonferenco

Member
Мне удалось реализовать на JavaScript достаточно быструю генерацию закрытых сесионных ключей криптоалгоритма Диффи-Хеллмана (при 2048-битном модуле и 256-битной экспоненте на это требовалось около 10 секунд или менее - на настольном ПК с двухядерным 3 ГГц процессором).
А можно ли Вас попросить переделать эту программу для практического использования непосредственным пользователем так, чтобы Алиса отправляла свой промежуточный результат Бобу и продолжала вырабатывать общий ключ только после получения от Боба его промежуточного результата? А то сейчас в её нынешнем виде программу можно использовать только для генерации псевдослучайных последовательностей.
И ещё три необязательные просьбы: 1) было бы неплохо итоговую экспоненту формировать не только из стандартного ГПВЧ, но и просить пользователя дополнить её своими случайными числами, 2) совместить обе html'ки в одну, чтобы пользователю не приходилось переименовывать файл констант из txt в js и прописывать его название во второй html'ке, 3) добавить возможность использовать генератор не только 2, но и ещё несколько других на выбор.
Спасибо.
 
Последнее редактирование:
moder

moder

Администратор
Команда форума
Так это не он сделал, это перекопирование материалов с Тора. Скачайте браузер Тор и перейдите по ссылке.
 
F

fxkonferenco

Member
Так это не он сделал, это перекопирование материалов с Тора. Скачайте браузер Тор и перейдите по ссылке.
К сожалению, это не возможно, так как в интернет я захожу с рабочего компьютера, а у нас администратор групповыми политиками ограничил права обычных пользователей на установку и выполнение дополнительных программ. Можно ли Вас попросить переслать мой первый комментарий на тот форум разработчику? Спасибо.
 
F

fxkonferenco

Member
Я нашёл программиста, который согласился переделать вторую страницу программы, скрипты которой согласовывают общий ключ. В тоже время первую страницу, которая генерирует промежуточные константы на основе выбранного модуля и указанной разрядности закрытого ключа, с библиотекой функций всё же нужно копировать с оригинального хранилища автора.
Ссылка на переделанную страницу: http://any.clubmeteorology.ru/dh/ (советую её сохранить себе на винчестер, так как автор может в любой момент её оттуда удалить).
 
F

fxkonferenco

Member
Всем привет!

Я переработал вторую страницу, ссылку на которую давал в предыдущем сообщении.

Кроме украшательства, была добавлена возможность генерировать открытый ключ двумя способами на выбор: 1) из парольной фразы или 2) совершенно случайным образом. Это было сделано из-за того, что стандартный генератор "случайных" чисел Math.random инициализируется таймером компьютера, чьей энтропии крайне мало для реального практического применения.

А теперь о том, как это работает. Парольная фраза инициализирует КСГПСЧ потокового шифра RC4, который генерирует гамму определённой в файле consts*.js длинны. Очевидно, что восстановить таким образом свой открытый ключ получится только в том случае, если используется тот же самый файл констант consts*.js. Также для экономии времени в этом же разделе интерфейса предусмотрена возможность восстановить из парольной фразы только секретную степень без дальнейшего подсчёта самого открытого ключа. Восстановление секретной степени из парольной фразы, безусловно, нарушает принцип perfect forward secrecy, однако может быть полезно для согласования общего ключа, когда получатель сообщения в момент его отправки не находится перед компьютером и не может согласовать общий одноразовый ключ. Делается это так: отправитель восстанавливает свою секретную степень (и, соответственно, свой долгосрочный открытый ключ) из своей парольной фразы, а для расчёта общего ключа шифрования использует долгосрочный открытый ключ получателя. В дальнейшем, когда получатель будет за компьютером, он сделает всё то же самое и точно так же посчитает общий ключ шифрования.

Действительно случайный способ генерирования секретной степени позволяет в полной мере использовать perfect forward secrecy, так как случайные числа получаются "оцифровыванием" :) движений курсора мыши, что в дальнейшем никак повторить не удастся.

"Тревожная" кнопка уничтожает все переменные: парольную фразу, общий ключ, секретную степень, а также открытые ключи и затем перезагружает страницу. По сути это аналог Ctrl+F5, но мне так было удобнее, когда я ловил ошибки в своих функциях.

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

Ссылка на мою переделку: https://drive.google.com/open?id=0B2Mdz6DZW9qQSzNUX19MbUtrdUk Сейчас она настроена на 2048-битный модуль и 384-битную секретную степень. Если вы используете другой файл констант consts*.js, то измените это в своей копии моей переделки. Также даю ссылку на минимальный набор дистрибутива (генератор констант, файл констант, ядро с длинной арифметикой и мой интерфейс): https://drive.google.com/file/d/0B2Mdz6DZW9qQX2pDV1U4STVYLVE/view (дополнительно архив прикреплён к этому сообщению).

Надеюсь моя работа будет вам полезна.
 

Вложения

F

fxkonferenco

Member
Всем привет!

Вижу, что темой заинтересовалось немного пользователей, потому решил добавить два замечания на счёт самого протокола Диффи-Хеллмана-Меркла и КСГПСЧ из потокового шифра RC4, который был использован в моей переделке.

Во-первых, протокол даёт возможность устанавливать только анонимные соединения между абонентами, когда ни одна из сторон не имеет возможности подтвердить свою личность без каких-либо дополнительных действий. Это означает, что вероятный нападающий, у которого есть возможность осуществлять активные действия в канале передачи данных (перехватывать, задерживать, изменять или удалять сообщения), может провести классическую атаку "Человек посередине" (https://ru.wikipedia.org/wiki/Атака_посредника), когда каждому из двоих абонентов он будет представляться его собеседником. И такой подлог может долго оставаться никак незамеченным, если злоумышленник будет просто ретранслировать сообщения абонентов друг другу, просто читая их или внося несущественные правки, которые его предположительно никак не выдадут.

Потому после криптографической защиты канала нужно как-то удостовериться, что вы общаетесь именно с тем человеком, за которого себя выдаёт ваш собеседник: проверить какой-то предварительно согласованый общий секрет, поинтересоваться подробностями какого-нибудь общего для вас события, которое (не)происходило в прошлом, или просто позвонить, если вы оба знакомы лично и хорошо знаете голоса друг друга, и проверить, какими открытыми ключами вы обменялись.

Во-вторых, недавно я заметил одну не очень хорошую особенность шифра RC4: если ввести парольную фразу, состоящую из одного и того же символа, то независимо от длинны такой парольной фразы, гамма будет одинаковая. То есть, парольные фразы 11111111 и 111111111111111111111111111111111111111 для RC4 полностью одинаковы.

Безусловно я далёк от мысли, что кто-нибудь из читающих это сообщение действительно додумается выбрать себе такую парольную фразу, и тем не менее предложу два способа, как можно защитить дурака от самого себя. Можно или дописать перед КСГПСЧ какую-нибудь криптостойкую хеш-функцию (например, SHA-2), которая сначала обработает парольную фразу, а потом уже её выход передать в RC4, или изменить саму процедуру засеивания ключевого массива (но в таком случае это будет уже не RC4, а что-то подобное на него).

В интернете полно javascript'овых реализаций различных криптостойких хеш-функций, потому прикрутить понравившуюся не должно составить особого труда, а для тех, кто захочет модифицировать процедуру засеивания ключеваого массива, укажу, где это сделать: в function RC4 нужно изменить строку j = (j + sbox + pasvorto.charCodeAt(i % pasvorto.length)) % 65536; так, чтобы код каждого символа парольной фразы зависел от его позиции в ней. Я бы переписал эту строку так: j = (j + sbox + ((i + 1) % pasvorto.length) * pasvorto.charCodeAt(i % pasvorto.length)) % 65536;. Единица ко счётчику "i" добавляется потому, что нумерация ячеек ключевого массива начинается с ноля, что при операции умножения совсем нехорошо, так как при любых обстоятельствах немало элементов ключевого массива были бы очень угадываемыми (ведь 0 * x = 0).

Если у вас возникают вопросы или есть какая-то критика, пишите в эту ветку. Всего хорошего!
 
Последнее редактирование:
F

fxkonferenco

Member
в function RC4 нужно изменить строку j = (j + sbox + pasvorto.charCodeAt(i % pasvorto.length)) % 65536; так, чтобы код каждого символа парольной фразы зависел от его позиции в ней. Я бы переписал эту строку так: j = (j + sbox + ((i + 1) % pasvorto.length) * pasvorto.charCodeAt(i % pasvorto.length)) % 65536;. Единица ко счётчику "i" добавляется потому, что нумерация ячеек ключевого массива начинается с ноля, что при операции умножения совсем нехорошо, так как при любых обстоятельствах немало элементов ключевого массива были бы очень угадываемыми (ведь 0 * x = 0).
Хотели как лучше, а получилось, как всегда. (с) Виктор Степанович Черномырдин

Только сейчас заметил, что строка сценария скопировалась без квадратных скобок после имени массива sbox. Наверное, их скушал форумный парсер, обрабатывая комментарий. И только сейчас я понял, что не туда добавляю единицу, чтобы избежать обнуления. Правильно должно быть так: j = (j + sbox[ i ] + (i % pasvorto.length + 1) * pasvorto.charCodeAt(i % pasvorto.length)) % 65536;
 
F

fxkonferenco

Member
Всем привет!
У меня для вас обновление, содержащее шесть разных изменений.

Несущественные:
1) текстовые поля сделал немного шире;
2) вставил ссылку на википедийную статью о протоколе Диффи-Хеллмана-Меркла и для примера на шифрующую программу, которой сам пользуюсь.
3) Добавил счётчик сгенерированных случайным образом бит.

Существенные:
4) теперь непосредственно перед запуском программы появляется настоятельная просьба уничтожать общий ключ шифрования сразу после его использования в шифрующей программе;
5) изменил функцию хеширования парольной фразы. Алгоритм остался прежний, но теперь первые 3072 значения гаммы отбрасываются. Подробности читайте в википедийной статье об RC4 и его модификациях.
6) Ещё одно дополнение к функции хеширования: все созданные в ней локальные переменные перед разименованием обнуляются. Это сделано на случай дампа оперативной памяти браузера и его дальнейшего исследования недоброжелателями. Однако я не уверен, что также обнуляются и локальные переменные в библиотеке DH.js, которая отвечает за длинные вычисления открытого и общего ключа. Потому в самом начале и прошу пользователей закрывать браузер, в котором согласовывался общий ключ, сразу после его использования в шифрующей программе.

Архив с обновлением прикреплён к этому комментарию, а также размещён на Google-диске тут: https://drive.google.com/open?id=1B8ZbYUX58efOqkX50B6XYESO1U8fzJ1j . В нём также четыре файла: генератор констант const_gen.htm, файл констант consts2048_384bit.js, ядро с длинной арифметикой DH.js и мой интерфейс dhm_with_human_face.html.

Для истории: количество скачиваний архива из комментария от 21 октября 2017 года - 137.
 

Вложения

Последнее редактирование:
F

fxkonferenco

Member
Добрый вечер!

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

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

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

Внешний вид генератора изменяет функция pliahazardo(), которая часть кнопок делает невидимой.

Дополнительная ссылка на Google-диск: https://drive.google.com/open?id=1mESrFea-Nn4jj0Z9spZGPlMy9P7nEmeW

Для истории:
1) количество скачиваний архива из комментария от 21 октября 2017 года - 210;
2) количество скачиваний архива из комментария от 28 сентября 2018 года - 84.
 

Вложения

Сверху