Open username1565 opened 3 years ago
Создан отдельный branch: nanoboard-unstable-changes. Там будут черновые наброски кода, с реализацией различных идей.
Теперь это ToDo-тред. Здесь я/мы буду/будем постить то, что я планируется впилить в наноборду. Просто, как идеи. Также, приветствуются и реализации этих идей - в виде кода.
Итак, поехали.
Первым делом, хотелось бы сделать замену постов, чтобы фиксить кривые посты, для нормального их отображения. Как я это вижу? Есть значит кривой пост, и есть его хэш. Создаётся некий файл с нормальным и исправленным контентом поста, и при вгрузке поста на клиент, контент заменяется на корректный конент, после чего пост парсится норм. Как сделать - пока не продумал, но оставлю как идею.
Дальше, хотелось бы впилить каптча-генератор. Чтобы можно было генерировать каптча-пак. Уже почти доделал, он будет в файле Captcha.cs.
Есть идея - впилить каптча-крякер, чтобы можно было брутить каптчи, и вводить их. Прикол здесь в том, что один раз решённая каптча, может использоваться ещё раз и ещё раз, и так много-много раз. Если решить миллион каптч, можно будет постить без каптчи, или сделать какие-нибудь пасскоды что-ли. Почти сделал уже, каптча-крякер будет вшит в файл Captcha.cs.
Хотелось бы также присобачить исходник Chaos.NaCl.dll
, чтобы не инклюдить пре-компиленную либу, а компилить всё это добро из исходника. Почти сделал.
Исходник NewtonSoft.JSON.dll слишком огромен, как его инклюдить - непонятно,
но хотелось бы прикрутить и его
чтобы вообще был полный опенсорц,
без всяких пре-компиленных библиотек и dll-лок
бинарных, внутрь которых может быть вшито - непонятно что.
Есть идея, прикрутить BigInteger.cs, с RSABigInteger'ом, а также BigInteger.js с RSABigInteger'ом, с последующей реализацией MITM-защищённого обмена данных, на базе полуанонимной аутентификации.
Вкратце:
1. ServerRSAprivkey - lite-server'a, скрыт.
2. ServerRSApubkey - lite-сервера открыт.
3. Клиент генерирует свой ClientRSAprivkey и получает из него ClientRSApubkey.
4. Клиент шифрует свой ClientRSApubkey, с помощью известного ему и открытого, пре-шаренного ServerRSApubkey, и получает EncryptedClientRSApubkey
5. Дальше, клиент подписывает EncryptedClientRSApubkey при помощи своего ClientRSAprivkey, получая SignedEncryptedClientRSApubkey.
6. После этого, клиент отправляет на сервер - пару значений (EncryptedClientRSApubkey, SignedEncryptedClientRSApubkey).
7. Cервер, дешифрует EncryptedClientRSApubkey при помощи своего ServerRSAprivkey, получая ClientRSApubkey.
8. Затем, сервер проверяет цифровую подпись клиента, по известному ему ClientRSApubkey, то есть проверяет подпись значения SignedEncryptedClientRSApubkey.
9. Если подпись ок - сервер генерирует рандом ServerRandomKey, затем шифрует его при помощи ClientRSApubkey, в EncryptedServerRandomKey, и тут же подписывает при помощи ServerRSAprivkey, получая SignedEncryptedServerRandomKey и отправляет клиенту это значение - SignedEncryptedServerRandomKey.
10. Клиент, получает SignedEncryptedServerRandomKey, проверяет подпись по известному ему ServerRSApubkey, извлекает из подписанного сообщения EncryptedServerRandomKey, дешифрует его своим приватным ключём ClientRSAprivkey, и извлекает рандом.
11. После этого, и клиент, и сервер, используют ServerRandomKey, в качестве ключа шифрования данных между ними. Например, это может быть шифр Вернама, обладающий доказанной абсолютной криптостойкостью. Длинный ключ Вернама, может быть образован синхронным, многократным хэшированием значения ServerRandomKey, который знает только клиент и сервер. При этом MITM-атакер, нифига не сможет сделать, походу.
12. Публичный ключ RSA-сервера - прешаренный. MITM-атакер не может подменить его.
13. Задеанонить клиента можно только в течении сессии, потому что RSA-ключи его генерируются рандомно, при каждом соединении.
14. Даже если MITM-атакер перехватит сообщение клиента, он нифига не сможет сделать.
15. MITM-атакер может также - подменить скрипты, чтобы клиент гнал трафик прозрачно на атакера, а атакер - шифровал инфу и гнал на сервер, но скрипты можно выкачать, и сравнить их хэш.
Вот такая схема, короче, MITM-защищённая.
Нафига всё это надо? Ну, хотя-бы для того, чтобы нанопосты в JSON, сливать и заливать, в зашифрованном виде, даже в LAN. Потому что они открытым текстом идут, по HTTP, и могут натыкать снифферов. А так - шифр. Но шифрование требует обмена ключем, а обмен ключами может быть подвержен MITM-атаке. Поэтому, схема обмена ключами должна бы быть MITM-защищённой, и RSA-шифрование с подписью, может исключить MITM, по вышеуказанной схеме.
Пока, это как набросок, без реализации, костыли, вроде впилил, а как полностью впилить - не знаю, и придётся многбукв написать. Просто оставлю это здесь.
Дальше... FractalGen.cs и NBPack.cs, и Captcha-Generator - можно было бы сделать отдельными приложениями, с Main, а не с Main_, запускать их как отдельные приложения, запустив nanodb.exe, с различными аргументами командной строки, а компилировать с основной точкой входа. Пока, это здесь, как идея, и пункт в ToDo-листе, но я уже знаю как сделать.
UPD: Вроде готово, вот здесь.
На DbApiHandler.cs хотелось бы подавать не только строки, но и бинарные данные. Нафига? А например, если постится пикча. В перспективе, можно из папки /download/ на lite-server'e, можно было бы сделать, полноценный тред с контейнерами - локальную, используя встроенную каптчу наноборды. То есть, дать возможность юзерам - ПОСТИТЬ туда контейнера, как в тред на борду.
Также, если в обе стороны, от клиента и к клиенту, гнать шифром JSON, то шифр - это бинарные данные, поэтому, надо бы сделать возможность постить на DbApiHandler.cs - бинарные данные тоже, а не только текстовые строки.
Есть идея переписать наноборду полностью на JavaScript, чтобы она работала в браузере. Например, каптча-пак-файл можно порезать на части, как тут nanoboard-javascript-captcha. Также, можно было бы использовать FileSystem API для хранения базы с постами, и client-side стеганографию в PNG, через canvas.
Была также идея, сделать HTML-сервер, чтобы он возвращал тупо HTML. Чтобы наноборда была совместима с браузерами, где отключен JavaScript, через который, client-side, парсятся нанопосты, получаемые в виде JSON. Как это делать, пока не представляю, ведь весь парсинг, придётся реализовать на серверной стороне. Может можно как-то попроще это сделать?..
Есть идея, пришпандорить сюда нормальную базу данных, с открытым кодом, например - SQLite. Какая должна быть структура базы данных, и как её впилить - пока не знаю.
Есть идея - создать скрытые разделы. Чтобы туда попадали скрытые посты, и скапливались там как говно, но чтобы их было видно, и чтобы их можно было найти по хэшам, и чтобы они не удалялись, иначе - это уже мочерация.
Есть идея, впилить алгоритм для F5 и поддержку jpeg. Например, есть js-jpeg-steg и F5-алгоритм на C#. Как это сделать - не пойму, но можно развить эту идею, кодом.
Есть идея впилить стеганографирование файлов в PNG.
Как я это вижу?
Первые 256 байт отводятся для имени файла, остальное место засирается контентом файла.
В итоге, можно было бы создавать PNG-контейнеры, с файлами различными,
и извлекать эти файлы из контейнеров,
просто запуская наноборду, как nanodb.exe NBPack -аргументы
.
Если впилить туда ещё и F5 алго
, то и с jpeg
'ами можно было бы просто работать.
Есть идея, запилить автобилдинг этого кода с помощью Azure Pipelines, на github'e, прямо из исходников, чтобы на выходе получилась автоматически nanodb.exe. Как это сделать - пока не знаю, просто намечу, на будущее.
Приветствую, @chu4ng
Я впилил капча-генератор, вот здесь: https://github.com/username1565/nanoboard/blob/beb5bdbd8467e5a4ed48c15679169b3323a98e2b/nanodb.exe-source/Captcha/Captcha.cs#L574 Он может генерировать отдельный нулёвый каптча-пак, с другими, случайными каптчами. 5 символов на каптчу, не так уж и сложно подобрать. Там 28 разрешённых символов. 24^5 = 7962624 вариантов, к перебору - максимум. Так что, каптчу, можно подобрать и циклом, на жаваскрипте. Вот она, нарезанная, тут: https://github.com/username1565/nanoboard-javascript-captcha Но если для одного поста подобрать каптчу просто, то для того чтобы сделать вайп - это уже сложно будет.
Ты говоришь, можно доставать каптч по хэшу. Да, можно. Но для этого, нужно решить миллион каптч (точнее 10241024 каптч в каптча-пак-файле). А это уже 1048576 каптч по 7962624 вариантов на каждую, максимум 7962624 1048576 = 8349416423424 вариантов к перебору.
И так как другой каптча-пак-файл очень просто перегенерировать с нуля, это обесценивает брутфорс и делает его энергетически нецелесообразным.
Дальше, ты говоришь майнить можно что-то. А что майнить-то? Чтобы что-то майнить, должна быть целая криптовалюта сделана, с блокчейном, который синхронизируется, и всякое такое. Впрочем, я знаю, что в отличие от биткоина, который основан на ECDSA, есть также криптовалюты на основе EdDSA, и библиотека Chaos.NaCl.dll, исходный код которой, полностью открыт здесь: https://github.com/username1565/nanoboard/tree/dev/nanodb.exe-source/Chaos.NaCl.dll она поддерживает работу с EdDSA.
Ну и хотелось бы знать, что именно ты хотел бы чтобы было переписано, и как?
https://github.com/username1565/nanoboard/issues/12#issuecomment-763908512 Вот эту идею, я немного пересмотрел.
Самый простой способ, реализовать, MITM-защищённую схему полуанонимной аутентификации, это... Использовать симметричное шифрование, с обменом ключем по протоколу Diffie-Hellman-Key-Exchange.
Судя по этому комменту: https://stackoverflow.com/a/19417336/8921172
Diffie-Hellman MITM'ается, однако если использовать pre-shared значения {p, g, A},
и вшить их в код скриптов на клиентской стороне, вычислить хэш этих скриптов, и расшарить их,
и расшарить {p, g, A}, чтобы их можно было сравнить при получении скриптов,
то тогда, MITM-атакер не сможет подменить {p, g, A} на свои,
и не зная а
(секретное значение, на сервере), он не сможет вычислить K
по B
, и дешифровать трафик между клиентом и сервером.
В качестве симметричного шифра, можно использовать Rijndael (AES), как на серверной, так и на клиентской стороне, а шифр гнать в бинарном виде, через отдельный хендлер. Имплементацией этого всего, я уже занялся, скоро закину тестовый код, черновой. Вроде работает.
UPD: Шифрохендлер с Diffie-Hellman-Key-Exchange и AES - готов. Вот он, во всей своей красе, многострочной: https://github.com/username1565/nanoboard/commit/b37d98bde5b675d53d21ab60082c0e820ea5e6cf Тест тут: https://github.com/username1565/nanoboard/blob/dev/pages/DHAES_test.html Скрипт - тут: https://github.com/username1565/nanoboard/blob/dev/scripts/DHAES.js Серверная сторона - в DbApiHandler.cs
@chu4ng , если хочешь чё-то майнить, или запилить крипту на каптчах, то глянь вот здесь, как для постов генерится каптча, и проверяется ответ. https://github.com/username1565/nanoboard/blob/beb5bdbd8467e5a4ed48c15679169b3323a98e2b/nanodb.exe-source/Captcha/Captcha.cs#L398-L407
Видишь, туда, в этот метод, заходит post
, и максимальное число каптч в каптча-пак-файле.
Выходит - индекс каптчи. Он зависит от куска хэша поста. Из поста, считается хэш, берутся первые три байта (это некое число от 0 до 16777216 (256256256) ), а затем, по модулю числа каптч в каптча-пак-файле, возвращается индекс каптчи.
Вот так вот, по хэшу последнего блока в блокчейне, можно генерировать текущую каптчу, для решения.
И кто первее её решит, тот и сгенерирует блок, смайнит его, и получит награду за блок.
Ручками. Человеки. Не асики и не процы и не видяшки.
Но... Тут есть одна миллипусенькая проблема...
И проблема эта заключается в том, что каптча тоже брутится!
Подбор 24^5 = 7962624
значений для одной каптчи не так уж и сложен,
ведь там всего 5 символов из 24 разрешённых символа
https://github.com/username1565/nanoboard/blob/beb5bdbd8467e5a4ed48c15679169b3323a98e2b/nanodb.exe-source/Captcha/Captcha.cs#L719
несмотря на необходимость рассчета 17210368
хэшей.
Может процессор будет долго это счетать, но кластер из многоядерных процессоров,
или видеокарта с её GPU-параллелизмом, или стойка из видеокарт, или ASIC, или ферма из ASIC'ов,
могут перебрать все варианты за время, сравнимое с блок-таймом.
Казалось бы, можно увеличить число символов в каптче.
Например сделать 20 символов.
Тогда уже, 24^10 = 63403380965376
намного больше чем 24^5 = 7962624
и сложнось майнинга повысится.
Я тоже думал об этом, но эти изменения сделают эту ветку наноборды обратно-несовместимой с оригинальной нанобордой.
Но несмотря на число символов, даже если асики не смогут подобрать каптчи, их могут подбирать хорошо организованные люди, и множество людей могут даже по одной букве распознавать и угадывать, и решать каптчи настолько быстро, что даже не успеешь прогрузить и увидить следующую - она уже будет решена. Какая-нибудь группа китайцев сядет и будет фанатично и быстро - майнить каптчами.
Быть может из-за ограниченного числа людей на планете, 7.5 миллиардов, такая крипта была бы и справедливой, и организованные группы китайцев, днями и ночами подбирающие и решающие каптчи эти, могли бы быть достойно вознагреждены монетами за свой труд, и такие монеты ценились бы на рынке выше, чем асикопремайнутые монеты, цены на которые постоянно болтаются на дне. Просто потому что каптчи решают люди, а не читерские вычислители всякие, вроде сверхбыстрых оптических FPGA.
Но так же само, вместо людей, распознавать буквы могут и нейросетки всякие, гугли машинное зрение, и программы распознавания текста из PDF, а также как работают сканеры документов. Видишь, какая проблематика?
И ещё... Каптчи, берутся из каптча-пак-файла, где их ограниченное количество. Если их пересчитать, и сохранить ответы, то можно решить каптчи для любого каптча-индекса, и для любого поста с любым хэшем. Если каптча-пак-файл использовать в крипте, то достаточно будет перебрутить его, и все блоки можно будет решить. Поэтому, так нельзя для крипты делать. И судя по этому коду: https://github.com/username1565/nanoboard/blob/beb5bdbd8467e5a4ed48c15679169b3323a98e2b/nanodb.exe-source/Captcha/Captcha.cs#L908-L917 Можно завязать следующую каптчу на хэш последнего блока, используя его в качестве сида, а в качестве текста, использовать некий рандом, завязанный на таймштамп времени генерации последнего блока, скажем, и/или какое-либо состояние сети (чтобы его нельзя было рассчитать заранее), но чтобы можно было проверить его наличие, по блокчейну. Скажем, дополнительным фактором рандомизации может быть хэш последней транзакции.
Запилил пира на шарпе, вот тут: https://github.com/username1565/CSharpServers/tree/Peer
Теперь бы sqlite прикрутить туда как-то, чтобы база данных могла быть большой. У меня есть репозитарий с хэш-таблицей на sqlite - вот тут https://github.com/username1565/KeyValue И недоделанный бранч с sqlite в наноборде - вот тут: https://github.com/username1565/nanoboard/tree/nanodb-sqlite Короче, базу вообще переделать бы в виде хэш-таблицы, и тогда уже можно было бы её раздавать в пиринговой сети, децентрализованно. Даже в локальной сети, можно было бы просинхронизировать базу. К тому же, если использовать sqlite, то можно вообще убрать нафиг ограничение на аттачи, и blob'ами их заливать туда (с каптчёй, разумеется). Каптча встроенная, что перспективно. Это всё пока лишь на уровне идеи, и очень много кодинга. Но, пожалуй - закину всё это в todo, для потомков.
Чё заделать здесь, как считаете?