[RU]

[EN]
Alphazine - Only Successful People.
ГАРАНТ ПОПОЛНИТЬ ДЕПОЗИТ

Вернуться   Alphazine - Only Successful People. > Общий > Криптовалюты. Блокчеин. ППМ. > Статьи.

[Определение часового пояса]
[ Регистрация ]
Имя:
Отделение людей от роботов


 
Опции темы
Делаем аппаратный криптовалютный кошелёк своими руками
Старый   #1
Admin
Админ
 
Регистрация: 01.01.2020
Сообщений: 1,684
Спасибо: 106 раз(а)
Репутация:    
Депозит: 0
БЛ: 24
Делаем аппаратный криптовалютный кошелёк своими руками

Обзор? Аппаратных кошельков? Ок. Соберём и обозрим тогда.

/*
*
* Стоит предупредить - из за порой интересной энергетики конкурса я не смог не позволить себе иногда подшучивать, язвить, иронизировать.
* Относись серьезно, пожалуйста, не к этому, - а именно к смысловому содержанию статьи.
*
*/


___ Эксprompt
___ Зачем всё это и "криптополитика"
___ ТЗ
___ Сборка
___ Преисполняемся в познании
___ Кодим
___ Сравнительный анализ
___ Выводы



___ Эксprompt


Это будет ебейший лонгрид, предупреждаю сразу. Начинать рекомендую с пятиградусных пивных напитков в духе сидра, а заканчивать - аспирином и плановым, в отличии от моего, сном. Создание своего устройства принципиально хоть как-либо качественно невозможно описать в 5 или около/менее тысяч символов.

Также вынужден предупредить сразу - очень маловероятно, что ты решишься так же стрелять себе в ногу, как это сделаю сегодня в твоей отрендеренной страничке браузера я.
И тому есть несколько весомых причин. Проект довольно объёмен, посему я просто не напишу даже за целый месяц всеобъемлющее описание всех его составляющих. Удалось максимально концептуально упростить интерфейсы взаимодействия продукта с пользователем, но пока что в силу объёма задач не удалось максимально упростить его для сборки тобой как энтузиастом.
т.е. собрать его конечно же по этой статье можно, но я банально физически не успею объяснить тебе, например, все нюансы рекомпила микропитона с нужными модулями под устаревающей убунтой (и не вижу смысла - любые статьи такого рода должны как по мне (и по правилам) описывать то, о чем не рассказано в гугле. Но, к сожалению, это неотъемлемые составляющие проекта). С некоторой частью важных в обучении себя вещей тебе придется столкнуться самому, я же опишу здесь всё самое интересное, значимое и, по моему мнению, что инновационного и удобного я пострался привнести в задумку. Имей некоторый технический уровень знаний перед реализацией.
Hard Level Proof of Concept короче.

Всё излагаемое изначально конкурса никак не касалось - я уже с полгодика и очень неспеша в этом во всем копался. Этот конкурс стал для проекта неким кикстартером на спидах - именно ты решишь, что дальше будет с проектом. Наверное, это не совсем красиво звучит, будто если я не займу какое-то значимое место - то забью или не буду стараться помогать в комментах, если кто-то таки решится делать всё это. Это не так. Просто это отнимает массу ресурсов, кои прямо пропорционально влияют на скорость и мотивацию. Это скорее намёк, что в случае выигрыша в конкурсе мои цели - не протусить бабки, а у меня был и есть конкретный интерес и вне конкурса довести проект до логической какой-то точки. Деньги сэкономят время, в общем. Вместе мы можем собрать интересный и, что важно - открытый продукт, и у меня есть чьей заручиться поддержкой в оффе, и какой-то результат сейчас - покажет значимость проекта всем и замотивирует и их помочь потом. Прототип работает, сам гуляю уже с ним некоторое время, но есть масса вещей которые хотелось бы оптимизировать. В идеале это должен быть user-dependend продукт, когда и ребёнок может приобрести готовое устройство и за 15 минут разобраться что и куда, и энтузиаст собрать вручную, заморачиваясь при этом не вопросами наличия аппаратных/программных закладок (потому что всё просто как валенки и покупаются отдельные ни с чем не связанные изначально компоненты, сборка - на уровне конструктора лего а прошивка лежит на гитхабе), а лишь тем, сможет ли он не криво это всё спаять или соединить на breadboard'е. И в конечном виде всё должно работать абсолютно одинаково для обоих представителей человеческой расы.
Вероятность закладки в покупаемом тобой микроконтроллере в миллионы раз меньше, чем вероятность закладки в условном Ledger Live - если ты с этим не согласен - у нас слишком различна логика и тебе не стоит дальше читать.

___ Зачем всё это и "криптополитика"

Ждал сравнение всего что мы сегодня напридумываем с уже успешными состоявшимися решениями, вроде трезора и леджера?) обо всем по порядку, сначала напридумываем и затем уже проведём сравнительный анализ.
Суть этой главы убедить тебя в том, что собрать своё устройство под свои нужды и быть уверенным в собственной безопасности не очень сложно, даже если опыт пайки у тебя ограничился лишь рассказами дяди Васи соседа электрика. (паять придется только ноги, и то - это можно делегировать в ближайший ремонт телефонов за банку пива (а то и вовсе за респект, у меня был под рукой паяльник))
Все преимущества, недостатки решения и почему я выбираю это вместо популярных - рассмотрим в одной из конечных глав.
И где ты ещё увидишь как какой-то типок походу обкурился и программирует аппаратный холодос на жабоскрипте и питоне?)))
Железки самому собирать далеко не так сложно. Интересно даже, почему до сих пор нет некоего отдельного подраздела на форуме по сборке своих устройств. То ли фантазии ни у кого нет, то ли время еще не пришло, то ли я ебанутый. Но это куда более созидательно, интересно, выгодно при правильном подходе, чем всякие запрещенные накануне рансомвары или прочая нечисть. Благодаря миру ардуино все процессы упрощаются до невозможности, и собрать становится возможным практически всё, на что хватает у тебя фантазии. Где не хватит характеристик - берёшь модель старше, где не хватит скиллов - топаешь на гитхаб, где не хватит терпения - есть масса готовых модулей и решений.

Касаемо криптополитики, чо за термин глупый такой.
Дабы не нарушить правила относительно копипаста, я лишь просто предложу ознакомиться по ссылке с заповедями жестких шифропанков, которые многим и мне в том числе приживаются и/или уже прижились, они являются для меня эталоном здоровой паранойи за свою безопасность - http://www.cypherpunks.ru. FAQ на сайте затыкает многих холиварщиков ответами элементарной логики на их безусловно вселенского масштаба вопросы, которыми они стартуют неделю на форумах с топика про "а какой мессенджер самый безопасный?" (привет, дамага)) thesecure.biz кому подняли? пгп кому придумали?)
Помни, мы стремимся тут соблюдать или хотя бы не нарушать эти важные штуки, речь идет об этом.


___ ТЗ

Че же мы делаем то? А собираем мы криптовалютный аппаратный кошелек с повышенной степенью безопасности.



Цитата:
Мои "стандарты безопасности" не основаны исключительно на каких-то ГОСТах или строгих ISO и стандартах - мы простые люди, и если я что-то придумываю, то стараюсь в первую очередь руководствоваться принципами ТРИЗ. Мои стандарты базируются на пережитом опыте, долгих наблюдениях, упомянутых выше заповедях - это всё уже может в итоге вполне сильно или наоборот лишь частично пересекаться с твоей безусловно ЦРУшной подготовкой хаксера.

На данном этапе для упрощения - только БТЦ, но
  1. Закладывая в архитектуру сразу же мультикоин'ность. (поддержку не одной криптовалюты)
  2. Хочу НИКОГДА не подключать его физически к устройствам с доступом к интернету (да и ни к каким устройствам способным услужить нам чем либо кроме питания всей электроцепи). это большая дыра в безопасности, так что хоть что-то у современных решений в безопасности как в старом анекдоте
  3. Хочу НЕ хранить в нём никакие приватные данные - вообще никакие, ни приватные ключи, ни сид фразы, ничего - у этого требования есть вытекающие важные преимущества и небольшие терпимые недостатки, подробнее в сравнительном анализе
  4. в качестве хранилища мне должно хватать головы (я здесь очевидно исключаю нездоровую память запоминать 12 слов, максимум позволителен пароль)
  5. Относительно простой ЯП для понимания (и оно сразу окажет еще одну услугу в упрощении разработки инфраструктуры). Я в душе машина, конечно, но еще не настолько, чтоб на асме или крестах статью катать)) пощади, самый близкий мне стек вообще пыха и питон. В целом, ЯП и устройства можешь выбрать любые, которые будут соответствовать всем требованиям. Микроконтроллеры уже и детскими штуками умудряются кодить, вроде тех где блоки визуально собираешь и оно работает хз как называется.
  6. Легко избавиться от sensitive данных в критической ситуации (а не прокалывать иголкой чип, окирпичивая девайс за 200 баксов боже упаси или и вовсе выкидывать его в окно, когда ещё не факт, что разобьётся в нём всё что нужно)
  7. Тачскрин - меньше дырок в корпусе в качестве кнопок - меньше путей его преодолеть. В идеале вообще запаять нахрен в стальную коробку. Можно, но только аккуратно - чтоб кирпич в сумке не таскать, рассчитывая конечный вес - залить в эпоксидку тонким слоем - и попробуй вскрыть и подменить фирмваре ничего не повредив за сжатые сроки.


___ Сборка

Касаемо железа. Ты волен выбрать любую аппаратную платформу, которая поддерживает изложенные чуть ниже криптографические функции в аппаратной их имплементации (быстрее чтоб было, но если совсем дурак - "эмулируй" в условиях интерпретации высокоуровневых ЯП, хозяин барин), а я же выбираю...

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

Я же выбираю в качестве головного устройства экзотику - отечественную Iskra JS https://amperka.ru/product/iskra-js - это аналог ардуинки, но микроконтроллер - STM32 и прошивка имеет встроенный яваскрипт интерпретатор. Он же в свою очередь из коробки умеет в парочку важнейших для нас криптографических функций, реализованных аж аппаратно. По сути, это - почти полная копия западной Espruino. А выделяя еще более абстрактно смысл - абсолютно похер, что из себя представляет покупаемая тобой плата - не даст мне соврать память, почти любую из стмок можно прошить прошивкой с интерпретатором жса через DFU или программатор, либо же захардкорься, не поленись, да реализуй всё на православном С/C++ и "чистой ардуинке" - если разовьюсь в крутой стартап - выкуплю у тебя прошивку)) У меня же что было под рукой - то я и взял.
В качестве периферии нам понадобится классный открытый проект OpenMV, я взял модель H7 https://openmv.io (стоп. Нахрена нам камера? а об этом попозже) и дисплей с тач скрином Nextion серии Enchanced https://nextion.tech (2.4 дюйма у меня лежал, больше - наверное, поприятнее глазу и в работе будет, сам смотри. У меня была претензия на компактность прототипа. И гляди чтоб у всего хватило ресурсов на наши финты ушами)

OpenMV тоже работает на стмке, на чуть чуть более мощной, работает на прошивке с интерпретатором Python'а - Micropython. Такова уж судьба, они нафигачили большую платформу распознавания на машинном обучении всякого интересного во фрейме, и чтоб было проще конечному юзеру - сделали это как раз на питоне - как на самом приближенном из простых языков к технологиям машинного обучения и распознавания картинок. Попса, короче, а нам это на руку - куча примеров для дебилов всех сортов, даже распознавать картинки самому не придется. Программируется через их собственную более-менее удобную IDE.

Некстион же представляет из себя дисплей, тач-скрин, микроконтроллер и всякую его периферию, в духе стабилизатора напруги итд, плюс фирмваре со встроенной программной платформой графического интерфейса и управления им. Кодится тоже через собственную IDE. Тут порекомендую обновлять прошивку через внешний отдельно покупаемый usb-uart преобразователь. С микросдшками я голову себе наморочил, завести так и не удалось - у них из коробки в качестве фичи есть проблемы с ними))) зато usb-uart без каких-либо проблем.

Отпаяй нахрен все микроюсбы, SD-card ридеры по итогу, если у тебя нет идеи корпуса с визуальным контролем вскрытия или вовсе подмены, или эпоксидка кажется тебе тяжелой темой.
И не забудь правильно согласовать логические уровни интерфейсов. Мне понадобился конвертер логических уровней.


Расточительно как-то, не правда ли? Три разных стмки, когда в трезоре всего одна. Но давай не будем забывать - мы собираем во-первых DIY PoC прототип, всё из заказанного мной на базу шло не более дня-двух, собирать свою отладочную плату куда дольше, во-вторых - собираю я из того что лежит под рукой, в-третьих - я уже кучу раз предупредил, что ты волен выбирать и компоновать что угодно и как угодно, моя задача - оголить перед тобой простоту сути создания подобного устройства, а не собрать самую эффективную аппаратную плафторму, конкурс таки о криптографии и криптовалютах, а не о железе, в-четвертых - перед трезором не стоит задачи распознавания визуального кода... (всё сильнее и сильнее интригую))) в пятых - перепрошил три МК, и устройство стало не аппаратным кошем, а, не знаю, системой видеонаблюдения или домофоном - на что хватит фантазии - удобно. И коммерческое серийно выпускаемое решение должно быть 150 раз переделано, оптимизировано и доведено до ума со всех сторон, так что до оптимизации ещё как Илону до Марса.



С требованиями вроде закончили, а теперь - более детально по некоторым неочевидным пунктам.
2) - тебе не придется подключать устройство к компутеру с интернетом, чтоб запушить транзу, если общаться оно будет с ним посредством QR кодов, контроль над генерацией которых ты будешь иметь чуть меньше чем полный. Даже бегло хоть визуально определить наличие "пейлоада" (если вдруг мы с тобой накосячили в их чтении и генерации, что уже крайне маловероятно) в нём проще, чем, скажем, в coinkite coldcard (канадском, дружественном нашему по принципам проекте) микро сд карточках.
Это требует наличия камеры и распознавающего вышеназванных кодов модуля в ней, но давай будем честны - что ты сейчас чаще видишь в устройстве с доступом в интернет - камеру или SD кардридер?))
3), 5) - Аккуратно подвёл к QR кодам, теперь можно и разъебать) Берёшь свои 12 слов, шифруешь их AES-256 (и в base64 конечно), пароль запоминаешь. Готов? барабанная дробь... Идешь на любое стекольно-гравировочное производство, показываешь им вот такой макет:








Просишь выгравировать QR код на таком вот кусочке стекла. Покупаешь так называемый "бейл", любую веревочку-цепочку, вешаешь на шею - готово. Ты сделал одно из самых дорогих украшений/аксессуаров в мире, если вдруг ты запрещенный рансомварщик)) дороже чем у западных реперов))) или гравирни на акрил/оргстекло, главное чтоб можно было вдребезги разбить/разломать без особых усилий при желании. Я же как настоящий сумашедший выбрал для прототипов стекло.
Ты НЕ хранишь никаких приватных данных в устройстве. Всё существует физически, и это даже хорошо. Довольно тонкий и маленький кусочек стекла с гравировкой на шее под одеждой очень легко сломать в несобираемый обратно вид (пусть даже соберут - остается AES) почти в любой сложной ситуации, будь то врывающийся ночью ОМОН или же допрос в аэропорту. Хранить 12 слов на листочке - это полный бред. Забыл где, потерял, оставил где попало - досвидос. Должен быть ОДИН экземпляр, должна быть возможность быстро от него избавиться - сломай тонкий кусок стекла (и попробуй восстановить потом гравировку до читаемого QR кода) и попробуй избавиться от листочка под подушкой (который ты, напомню, склонировал несколько раз и распихал по всем тайникам в квартире чтоб не потерять, плюс в открытом виде). Опасно порезаться при разбивании, да не опаснее чем то, от чего ты этим проектом собрался бежать. Думаю, детальнее обсудим это в сравнительном анализе, если ты ещё не понял, о чём речь.
4) - JS уже практически везде. На нём делают бэк, фронт, игры, его суют детям, его интерпретирует любой браузер. У меня на нём есть мощный жаббер-пгп клиент под личные цели. Теперь на нём программируют микроконтроллеры. Делаем сайнер (от англ. signer - подписыватель, наше устройство по сути будет лишь подписывать транзакции, когда аналоги хранят в себе приватные данные. Так что формально сам "кошелёк" у тебя на шее в виде стекла), делаем пушер, который схавает любой webview, хоть в мини приложение ВКонтакте кои на реакте клепают его засунь, я уж молчу про элементарность имплементации в удобохаваемый любой мобилой и осью вид. Это тебе не Делфи, земля ему пухом))

Остальное, думаю, ясно.

Стартуем.

Начнем со сборки электроцепи. Напомню, что запитать нам нужно три разных микроконтроллера STM32 на платах с разновольтовой логикой. Камера и искра - 3.3, у них стаб напруги один типо похожий и они совместимы, а на экранчике понижающий регулятор LR6209, который судя по даташитам понижает 5 до 3, но куда проще таки конвертер логических уровней с поддержкой UART, у меня скормить ему 3.3 с выводов 3v3 не получилось без лагов. Докупай конвертеры, либо выпаивай стабы, делай что вздумается. Питание - дело вкуса. В идеале круто сделать беспроводную зарядку в духе https://mcustore.ru/store/moduli-pit...pitanya-5v-2a/ - это отлично вписывается в эпоксидку, хоть и должно по логике весь этот кирпич слегка нагревать. Зато 200% невозможности передавать данные па правадам.

Общение между устройствами - сильно выбирать не приходится. Некстион общается с управляющим МК по интерфейсу UART - резервируй ноги, а в моей искре юарт всего один, так что дружить опять же для экономии ног камеру с ней я решил по интерфейсу I2C. Данных слишком много бегать не будет - самое большое, что нас ждёт - передавать матрицу QR-кода, с чем спокойно оба интерфейса справятся.
Устройство готово! Чуть позже погоняем туда сюда десятки байт темплейтными примерами работы с интерфейсами, дабы убедиться что всё работает и мы не дураки.



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

___ Преисполняемся в познании

Пришло время кишков.
Что вообще такое криптовалютный кошелёк и как он существует в аппаратной плоскости?

Мой онлайн кошелек генерирует мне некую последовательность символов, именуемую публичным ключом. Мне друг на него деньги шлет.
У меня есть и приватный ключ, благодаря которому я могу распоряжаться присвоенными публичному ключу в блокчейне монетами.
Какое отношение имеют к этому всему некие 12/24-слов фразы? Неужели все авторы веб-кошельков создали единую базу резервных кодов восстановления длиной 12/24-слов и благодаря этому я могу восстановить свой кош в другом веб-коше?

Криптография не обошла стороной и этот невероятно важный для нас вопрос.
Есть такое важное понятие как "HD Wallet". И это абсолютли не High Defenition, коего качества порно смотрят детки с соседних школобордов. Это ничто иное как Hierarchical Determenistic. Иерархически детерминированная система - система, в которой есть место некоей иерархии и нет невозможности определить поведение.
Эта система была внедрена разработчиками биткоина в Bitcoin Improvement Proposals - в документах, в которых публично выдвигают предложения по улучшению архитектуры бтц. HD коши появились в BIP-32, мнемонические 12/24-слов фразы - в BIP-39, мультиаккаунтная иерархия для них - в BIP-44 и так далее.
Что же нам делать с этой информацией? Разобраться, как современные решения генерируют кошелек и какие его части потом для чего используют.
Проследуем в BIP-39:
Для того что бы сгенерировать кошелёк - генерируем кратную тридцати двум энтропию бит, например 128. Хоть руками по клаве натыкай. Берём SHA-256 от первых 128/32 бит энтропии и добавляем в конец последовательности, делим на куски по 11 бит ииии.... Эти 11 бит кодируют 2048 слов из https://github.com/bitcoin/bips/blob...39/english.txt этого списка! Поздравляю - мнемоника, равно как и иерархически детерминированный кошелек готовы.
На основании этой энтропии уже генерируется вся иерархия по BIP-32, детальнее - ознакомься с этой картинкой и в гугле, и пойми, где находятся затронутые в одной из предыдущих конкурсных статей xpriv и xpub, где находятся те самые адреса, которые ты показываешь клиенту при оплате твоих услуг, каким образом они происходят из этой мнемоники.






ещё один важный элемент - это система адресации. Так называемый Derivation Path.
Генерить-то адреса это классно, а как же иметь возможность обращаться к старым? На то оно нам и пригодилось.
Каждый бтц адрес имеет свой адрес, и понимай эту тафтологию как хочешь.
Выглядят адреса адресов как-то так:


Цитата:
m / purpose' / coin_type' / account' / change / address_index
Например,:
m/44'/0'/1'/0/19
  • m - константа
  • 44' - тоже, это своего рода "какому бипу мы соответствуем с этим Derivation path"
  • 0' - монетка, нолик это бтц (как ты догадался - в этом моменте у нас и будет мультикоинность - меняй цифорку, а методы работы плююююс мииинус одни и те же)
  • 1' - "аккаунт", некоторые онлайн коши воспринимают только нулевой, из-за чего я наткнулся на способность спрятать бтц с глаз долой в таких веб-кошах
  • 0 - 0 если адрес хочешь юзнуть для получения денег извне и 1 если хочешь юзнуть адрес чтоб вернуть себе на него сдачу. Особенно ни на что не влияет, кроме приваси (что важно, но этого мы не касаемся сегодня).
  • 19 - собственно айдишник адреса.
Имея на руках мнемонику и путь деривации можно вычислить пару ключей и использовать соответствующий им адрес кошелька в целях получения или отправки денег.

Потому, пусть 12 каких-то случайных слов некоторым старожилам и не казались раньше чем-то надёжным с точки зрения получения доступа к своим криптовалютам, вспоминая школьную комбинаторику - есть 2048^12 разных фраз. Легко угадать наобум? Не очень. А теперь представь 2048^24.
Коши лапками генерить научились.
Суть становится всё ближе...



Цитата:
Я говорил тебе закатать свою свежесгенеренную мнемонику в AES, QR и гравирнуть на стекло. Это избавляет тебя от удобной возможности сменить в корне вещей твой кошелёк, сгенерировав фразу еще раз. Но относись к кошельку бережнее и понимай больше, чем люди вокруг - и менять его тебе не придётся никогда в жизни. На крайняк - закажешь еще стекляшку. Зачем выдумывать некие Secure Element чипы, которые теоретически и практически уязвимы https://www.kaspersky.ru/blog/hardwa...-hacked/22183/ https://www.iguides.ru/main/security...ty_bolshe_net/. Вайт хет, хоть обкакайся - взламывать буквально просто нечего. Расшифрованная мнемоника появляется в памяти микроконтроллера только во время подписывания транзакции. На крайний случай - выключение устройства очищает всё что только можно. Его не страшно терять, дарить, оно - посредник, а не хранилище во всех ипостасях, как это глупо происходит сейчас у наших с тобой конкурентов.
Остальные преимущества и недостатки такого подхода всё равно ниже, тут это просто к слову.

Как же в итоге всё должно работать?
На ПК с интернетом у тебя есть xpub - более менее открытая инфа, её не страшно хранить на пк с сетью (так происходит и у всех аналогов, правда они ещё привязывают твой xpub в бд к твоим почте и прочим данным - смекаешь?):
  1. С помощью него ты смотришь свои деньжища
  2. Генерируешь транзакцию
  3. Генеришь её QR код
  4. Сканируешь его с помощью нашего устройства
  5. Сканируешь стекло с помощью устройства
  6. Вводишь пасс на Nextion в устройство для расшифровки мнемоники под AES со стекла
  7. Наш девайс подписывает транзакцию и выводит на дисплей QR код с уже подписанной транзой
  8. Сканишь QR устройством с инетом с нехтиона и пушишь подписанную транзакцию в сеть

Профит! Важнейшую и самую опасную часть всего манаджинга криптовалюты - подпись транзакций - мы вынесли в отдельное устройство, самую приватную инфу вообще обернули в физическую оболочку и обезопасили AES, а все безопасные действия, вроде генерации публичных адресов ты можешь делать где угодно, не боясь за сохранность своих средств.
Никаких "запишите эти 12 слов восстановления и засуньте поглубже в задницу", помни лишь один единственный пароль от AES, как ты помнишь его от своей рабочей тачки и таскай маленькое стеклышко, которое вполне сходит за модный киберпанковый аксессуар для себя и вполне просто прячется под любой одеждой от других.
Кодим.

___ Кодим

Декомпозировать работу можно в разрезы с нескольких разных сторон, я попытаюсь как-нибудь по-универсальнее всё вместе сложить.
Условно работу можно разделить на 3 этапа:
1) Главный МК искра
2) Камера
3) Веб "кош" который работает только с xpub (выше писал - создавать адреса, транзы, генерить QR, пушить подписанные tx в сеть) (тут мы немножко пока схалявим, потому что тоже потянет на отдельную статью. Это сделаю я сам когда того потребует ситуация, а сейчас для "PoC" можно будет обойтись тем что я предложу на этом этапе)
Дисплея тут нет, потому что среда разработки для него представляет из себя визуальный редактор - перетащил кнопочки, поменял цвета и готово. Ну уж как нибудь сам разберешься епт как кнопочки перетащить)) Рисовать QR коды подписанных транз мы всё равно будем с главного МК - так случилось из-за некоторых ограничений дисплея, о чём чуть позже, так что нам понадобится то всего несколько команд знать.

Подводные камни есть во всех сферах жизнедеятельности, особенно в дайвинге.

Есть ещё один пунктик. Как же нам определить, каким именно приватным ключём, который мы должны генерить сами из мнемоники на головном МК подписывать транзу? Всё очень просто. Я предлагаю передавать Derivation Path вместе с неподписанной транзой в QR. Это просто - {derivation_path}|{unsigned_tx} и распарсил при сканировании.

Каков алгоритм работы.
При включении устройства, задача искрухи сразу же - просто ждать расшифрованный QR код с камеры, который придёт по I2C.
С ним работать просто - I2C это всего лишь двунаправленная последовательная асимметричная шина для связи между интегральными схемами.
Не плачь. Просто соедини проводки как нужно - плюс к плюсу, землю к земле, SCL->SCL, SDA->SDA и идём кодить))


(редактор от кол-ва текста не грузит предварительный просмотр и я не знаю, указан ли язык листинга, так что на всякий случай подпишу у каждого)
JS:

Код:
I2C2.setup({sda: B3, scl: B10, bitrate: 19200}); // коннектимся
setInterval(()=>{
    var myTwoBytes = I2C2.readFrom(0x12, 2);    //сначала ждем два байта сайза будущих данных, 0x12 - это адрес камеры на шине
    console.log("==="+parseInt(myTwoBytes)+'===');
    var txt = I2C2.readFrom(0x12, parseInt(myTwoBytes)); // парсим ровно сколько нам обещали
    txt = String.fromCharCode.apply(null, txt);
    console.log("==="+txt+"===");
},500); //каждые полсекунды чёто ждём от камеры
в то же время на камере (уточню, что примеры почти всех важных для нас кусков кода именно камеры оказались в примерах в самой IDE, причём там еще дофига интересного. На досуге поиграйся! Здесь нам лишь останется всё правильно организовать и допилить):



Python

Код:
import pyb, ustruct
text = "Hello World!\n"
data = ustruct.pack("<%ds" % len(text), text)
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12)
bus.deinit() # так нужно. Интересно - почитай про I2C, Master и Slave
bus = pyb.I2C(2, pyb.I2C.SLAVE, addr=0x12) # задаём адрес на шине и инициализируемся
print("Waiting for Arduino...")
while(True):
    try:
        bus.send(ustruct.pack("<h", len(data)), timeout=1000) # опа, шлём наши два байта
        try:
            bus.send(data, timeout=1000) # шлём сами данные
        except OSError as err:
            print(err)
        print("Sent Data!")
    except OSError as err:
        print(err)
кайф! Они научились общаться.
Топаем дальше. Сканим коды:

Python:

Код:
import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must turn this off to prevent image washout...
clock = time.clock()
while(True):
    clock.tick()
    img = sensor.snapshot().negate() # в негативе?? почему??????? поясняю ниже
    img.lens_corr(1.8) # strength of 1.8 is good for the 2.8mm lens.
    for code in img.find_qrcodes():
        img.draw_rectangle(code.rect(), color = (255, 0, 0)) # обрисовывает красным квадратиком для наглядности в IDE
        print(code) # вот и всё! осталось лишь отправить его по I2C
Поясняю за негатив. Если ты попробуешь отсканировать обыкновенный QR код этой OpenMV H7 - всё пройдёт абсолютно без проблем. А теперь попробуй отсканить белую гравировку QR кода на СТЕКЛЕ. Конечно, когда ребята тренили нейросеть для распознавания кодов - они на такие понты не рассчитывали, потому в датасете белого цвета кодов и не оказалось.
Можно было бы перетренить её, но это тема для отдельной статьи, так что этот подводный камушек мы обойдём красиво - прикладывай своё стекло к чему-нибудь чёрному и в негативе QR код тоже становится чёрным и распознаваемым.
Да, это к сожалению пока что не айфона камера, которая распознаёт любой QR за доли секунды. Но пользоваться вполне можно, шибких проблем не испытываю.
Негатив снапшоту очевидно нужен лишь при скане именно стекла, а обыкновенный черный по белому код он как раз таки превратит обратно в проблему, не забудь.




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

Сканить мы научились.
Научимся общаться с экранчиком, напомню, по интерфейсу UART:

JS:

Код:
Serial1.setup(9600, {tx:B6,rx:B7});//законнектились, TX->RX RX->TX

function makeid(length) { 
    var result           = [];
    var characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var charactersLength = characters.length;
    for ( var i = 0; i < length; i++ ) {
      result.push(characters.charAt(Math.floor(Math.random() * 
 charactersLength)));
   }
   return result.join('');
}

Serial1.on('data', (data) => { // при получении данных
  
LED2.write(true); // моргаем светодиодом для наглядности
  console.log(data); //выведем что получили
  Serial1.write('t0.txt="'+makeid(5)+'"\xff\xff\xff');  //я шлю экранчику команду поменять свойство тхт объекта т0 на случайно сгенерированную строку, t0 это просто текстовый Label, и оканчиваю всю команду завершающей последовательностью "\xff\xff\xff"
  
setTimeout(()=>{
    LED2.write(false);
  },200);

});
Команд в программном интерфейсе нехтиона - на 10 минут изучения, так что не вижу смысла здесь описывать, официальная дока на одну страницу уместила описание всех.
В обработчике нажатия на кнопку в этом примере у меня написано sendme, что присылает по юарт текущую страничку либо же просто можно print "hello" А дальше алгоритм уже очевиден:
Ждём QR с неподписанной транзой и метаинформацией в виде путя деривации, после этого сразу же ждём QR со стекляшки, открываем на дисплее страницу с заранее нарисованной клавиатурой и просьбой ввести пароль, соберя в Nextion Editor клавиатурку в духе:



или


на что хватит твоих дизайнерских способностей.
полученным паролем, юзая функции из библы crypto на искре расшифровываем полученную из QR кода мнемонику:
JS:

Код:
...
var crypto = require('crypto');
var encodedAndParsedMnemonic;
var mnemonicAesPassword;
var salt; //если вдруг была и/или нужна
 
var secretKey = crypto.PBKDF2(mnemonicAesPassword, salt, {
  keySize: 4,   // не проеби это всё при шифровании в стекло (примечание автора - здесь под "это всё" я имею ввиду все аргументы инициализации процесса крипта/декрипта, вектор инициализации кол-во итераций соль итд, а то так один прототип был благополучно восран)))
  iterations: 2,
  hasher: 'SHA256'
});
 
 
var decryptedData = crypto.AES.decrypt(encodedAndParsedMnemonic, secretKey);
var decryptedText = '';
for(var c=0; c < decryptedData.length; c++) {
  decryptedText += String.fromCharCode(decryptedData[c]);
}
print('Decrypted mnemonic: ', decryptedText);
...
Гуд! У нас на руках неподписанная транза и мнемоника.
Теперь, портировав и вытащив нужные функции из любых жс библ (есть даже официально референснутые из бипов https://github.com/bitcoinjs/bitcoinjs-lib), подписываем транзу:

JS:

Код:
...
var decryptedMnemonic;
var parsedDerivationPath;
var unsignedTxHex;

var seed = bitcoinjs.bip39.mnemonicToSeedSync(decryptedMnemonic);
var root = bitcoinjs.bip32.fromSeed(seed);

var keyPair = root.derivePath(parsedDerivationPath); // топаем до нужного адреса

var tx = bitcoinjs.Transaction.fromHex(unsignedTxHex); //декодим из хекса в либовую структуру
//здесь где-нибудь обязательно показываем юзеру на экран инфу о совершаемой транзе - сумму, кош destination и просим подтверждение
tx.sign(0, keyPair); // Подписываем
let signedHexTX = tx.build().toHex(); // готово
console.log(signedHexTX);
...
Кайф! Подписали. Теперь самое, казалось бы, простое - вывести её на дисплей?
Nextion имеет свой собственный элемент граф. интерфейса - QR код.
Проследуем вчитаться в доки:
"The QRcode component is used to generate a 2D scanable QR. It is limited to a byte maximum for the .txt_maxl attribute of 84 (of up to a max 154 bytes) on Basic T models and 192 bytes on the Enhanced K and Intelligent P models."

Ну епт, у нас подписанная транза с одним входом и двумя выходами минимум в два раза больше чем 192 байта. Зашибись.
На искре генерить тоже не вариант - генерация такого кью ара выползает за лимиты памяти.
Остаётся только камера. Кесарю - кесарево, короче. Кодами занимается камера, криптографией - головной МК и графикой - МК дисплея. Хотя бы четко))
Места в памяти камеры не хватит и под остальной код, и под генер кодов, так что поступим иначе. Пошерстим по сети и наткнемся на очень интересную сишную библиотеку - https://github.com/coinkite/mpy-qr опаааа! да ты посмотри кто её автор! Да это ж наши ближайшие конкуренты - Coinkite! Похоже - экспериментируют что-то или прямо сейчас пыхтят именно над тем, что мы и делаем. Общение в их девайсе они предпочитают с помощью SD кард, а тут аж библа под микропитон. Подозрительно...
Красиво. Библа все равно не их, они лишь врапнули её в измерение микропитона. Так что даже совесть чиста.

Качаем ебунту 14.04, ставим её в качестве виртуалки, качем набор необходимых зависимостей - гит, пакет разработчика под арм - https://github.com/openmv/openmv/blo.../src/README.md - не благодари.
Клонируем сорцы фирмвари OpenMV, пихаем модуль в микропитон, компилим микропитон с ним, компилим фирмварю камеры, загружаем - вуаля! Теперь нам доступна ныне "системная" библотека uqr, которая возвращает аж целый "a 3-tuple with (width, height, pixel_data). Pixel data is 8-bit packed, and padded so that each row is byte-aligned. The padding is at the right side of the image and will be: 0 < (width-height) < 8". Что невероятно удобно, как ты понял.
А жаль, либы на жсе генерили убогий svg на квадратиках, с которым работать ещё проще)) но ничего страшного. Зато более эффективно.
Передаём по I2C хекс подписанной транзы с искры на камеру, генерим QR, затем 3-tuple шлем обратно на искру.
Это будет не самый быстрый рендеринг, но теперь воспользуемся элементарностью некстиона:



Цитата:
line - Draw a line from point to point with specified color
usage: line <x1>,<y1>,<x2>,<y2>,<color>
<x1> is the x coordinate of the starting point of the line to be drawn
<y1> is the y coordinate of the starting point of the line to be drawn
<x2> is the x coordinate of the ending point of the line to be drawn
<y2> is the y coordinate of the ending point of the line to be drawn
<color> is line color, either decimal 565 Color Value or Color Constant
line 20,30,170,200,BLUE // draws line in BLUE from (20,30) to (170,200)

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

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

Всего я тебе прямо щас закодить не успею, мне тоже спать иногда нужно)) так что пока что в качестве коша для генерации транз и работы с xpub воспользуемся этими двумя тулзами (или любыми другими подобными)(обе на жсе, вот о чем я говорил)) и вот то самое небольшое "пока что схалявить" - один фиг, итогом будет соединённая красивая версия этих двух тулз) -
- https://peli-pro.github.io/coldcard_address_generator/ - генератор адресов по xpub'у
- https://coinb.in/#home - New -> Transaction -> сделал транзу, добавил к ней по твоей схеме парсинга derivation path (помнишь же? мы его передаём с неподписанной транзой) -> сделал QR код -> отсканил устройством и далее - только что проходили. Затем зашел во вкладку Broadcast и запушил её подписанную в сеть.
Поздравляю, вы великолепны!

___ Сравнительный анализ

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

Тем более, что вообще лучше всего покажет нужно ли было вообще всем этим заниматься, если не сравнительный анализ?

Ledger, Trezor, Coinkite ColdCard и наш красауец.
Первые два - как самые известные, и третий из-за нифиговой такой по значимости отметки Loved by Cypherpunks на сайте (и им пользуются серьезные ребята отсюда и не только).



Красные ячейки - баллов не дают, желтые - 0.5 балла, зеленые - 1 балл, итого:
Ledger - 3
Trezor - 3.5
ColdCard - 6
Наше чудо-юдо - 11.5!

А кто-то тут не так давно заикнулся, мол что ещё интересного можно рассказать про аппаратники...


Необходимо дать некоторые пояснения по критериям, цветам и информации:
-Открыт код устройства? - очевидно
-Открыт код компьютерного клиента? - colcard получил желтую "сомнительную" оценку, потому что неопытный пользователь может спокойно выбрать опасный кошелек с закрытым исходным кодом, открывая простор как минимум для слежки.
-Хранение приватных данных - ключевой обсуждаемый всю статью момент, всё очевидно
-Легко ли уничтожить приватные данные? - опять хоть как-то о быстром окирпичивании девайса (не считая просто выбросить его в окно) позаботился лишь CoinKite - прямо около их Secure чипа есть надпись "Shoot this":






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

-Передача данных на устройство-пушер и Требуется ли проводное подключение - думаю, можно оставить необходимость подключения устройства посредством провода к потенциально уязвимому ПК без комментариев. Мы с ColdCard справились лучше, однако получили всего по 0.5 балла, и есть причина почему не по целому. Физически и глазами гораздо проще контроллировать безопасность - убедиться, что твою MicroSD карточку не подменили, что QR коды ты сгенерировал сам и только что, но определённого рода уязвимости можно теоретически найти в обработчиках получаемой и генераторах отправляемой информации - при считывании данных с MicroSD или распознавании QR кодов, потому и по пол балла, а не по одному.

-Атака посредника - когда Ledger не показывал на дисплее полностью адрес, куда ты собрался отправлять монетки - за N-ресурсов можно было генерировать очень похожие адреса, и разница в них была скрыта под точками - 1b2woc...2cihx1 и 1b2woc...2cihx1 - что под точками-то?
Прецедент у Леджера был, сейчас всё пофиксили, так почему 0 баллов то? А всё просто - такая банальная уязвимость, которая бросается в глаза даже не разработчику устройств или ПО, сразу может рассказать об отношении компании к своему продукту. Мы же сделали это сразу (см. комментарии в коде, я строго отметил момент где нужно показать инфу юзеру), остальных участников в подобном уличить не удавалось.

-Вектор атак через обновления прошивки - всё просто. Прошивка открыта - её легко модифицировать, за что Ledger получил свои пол балла, а мы с догоняющим ColdCard вышли победителями в этом пункте по другой причине, которая напрямую взаимосвязана с необходимостью проводного подключения устройства к ПК - думаю, дофантазировать не сложно, о чём идет речь������

-Вектор атак на обход пин-кода - вольтажный сбой, эксплуатация часов, брутфорс - в нашем девайсе ничего не хранится, соответственно и взламывать по сути нечего. А что легче сбрутфорсить - 6-ти символьный пин-код из 0-9, или AES-256?

-Атака «ящика для носков» - когда ты наплодил себе листочков со своей мнемоникой и раскидал их по всей базе, в том числе засунув в ящик для носков. Посуди сам, ты же не распихиваешь так называемые "бэкапы" пароля от рабочей тачки под подушки, матрасы, носки и шкафы? Не делаешь дубликаты ключей от квартиры, не делаешь дубликаты дебетовой карты и так далее.

-Атака на цепь поставок - гипотетическая возможность подменить девайс до получения его тобой после покупки. Пусть и у 3-х претендентов открыт код, никто не исключал пока что реальность аппаратных закладок. В наш продукт, как я писал изначально - хочется интегрировать возможность собрать его полностью самому, что исключит или усложнит в тысячи раз возможность реализации всех векторов атак на цепи поставок.

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

-Атака через слежку - всё просто, это возможность банально подсмотреть у тебя пин-код. То, от чего Сноуден прятался под одеялом, вводя пароль на ноутбуке.
Почему же у нас плюсик, но пол балла?) всё просто. У нас, во-первых, не пинкод - а пароль, что усложняет уже. Во-вторых, для самых опасливых, у меня есть фича и на этот счёт, но в виду объёма статьи оставлю её тебе на досуг - https://habr.com/ru/post/133473/ + рандомизация выводимых символов на клавиатуре при введении пароля расшифровки мнемоники. Если с экраном ты ещё такое на других устройствах может и провернёшь, то что собрался делать с хардварной клавиатурой ввода пин-кода или закрытой прошивкой?)

__ Выводы

Конечно - сравнительный анализ довольно условен, - мы собрали грубый прототип, но, тем не менее, уже на его основе можно поглядеть конкретный отрыв в качестве подходов к безопасности в сравнении с популярнейшими решениями. Я считаю, что доверять тому, что красиво выглядит и собрало очень много денег в раундах инвестиций от венчурных фондов - дело такое себе, когда можно без огромных сложностей собрать самому и лучше, да и красота - штука довольно субъективная.
Наше устройство - прототип, но он работает, а значит самое сложное и важное мы уже проделали в этой статье.
Есть ещё много над чем работать, ждёт большой путь, но собственная безопасность стоит того всегда.
Безопасность - право человека, а не побочный продукт естественного эгоизма.



Автор: Noizefan
  Ответить с цитированием
Старый   #2
Admin
Админ
 
Регистрация: 01.01.2020
Сообщений: 1,684
Спасибо: 106 раз(а)
Репутация:    
Депозит: 0
БЛ: 24


Архив с прошивкой (ещё тестим, стоит "0.1" не просто так): anonfiles.com/zeJdh4F9u8/b1_rar
  Ответить с цитированием
Опции темы
Опции просмотра