Авторизация
Регистрация

Напомнить пароль

Аппаратный менеджер паролей с шифрованием. Коммерческий проект

Не скажу что когда-то задумывался о таком, но после отправки клиенту захотел себе :) Встречайте, аппаратное хранилище авторизационных данных с шифрованием, Wi-fi веб-сервером для смены паролей и цветастой индикацией, умещающееся в кармане. Код и модели выложены в открытый доступ под лиценизей GPL 3.0 — копирование, улучшение и продажа приветствуются, но только если код и модели вашего проекта будут открыты общественности!

С заказчиком оперативно обговорили ТЗ и сошлись на хранилище-флешке с тремя кнопками — каждая должна соответствовать своему паролю. Что-то вроде такого, но поменьше кнопок.


Чтобы не плодить дополнительных программ для смены пароля (а смена — фича обязательная), было решено реализовать ее с помощью веб-сервера через точку доступа. Также заказчик попросил, чтобы его пароли не лежали в открытом виде. Последняя просьба прозвучала немного странно, ибо нажатие кнопки вводит пароль в совершенно открытом виде… Но ладно, шифрование так шифрование. Пусть будет AES-256.


Итого я решил делать устройство на базе ESP32-S3 Mini. Это компактная плата с поддержкой аппаратной эмуляции клавиатуры через USB, а еще туда встроен RGB-светодиод на протоколе NeoPixel. Это означает, что заморачиваться с индикацией не придется вовсе.


По аппаратной компоновке я изначально решил, что разводить плату не стоит — у нас пара кнопок всего на схеме. Но и на проводках лепить я их не стал. Вместо этого припаял кнопки как есть к отладочной плате.


Выставив один из пинов кнопки в режим OUTPUT LOW, можно реализовать «программную» землю. То есть мне даже не нужно подключать кнопки к земле — а значит и выводить лишние провода.

Третья кнопка уже встроена на плате и подключена к пину 0. Она выполняет две функции. Если зажать ее и включить питание, плата войдет в режим прошивки. А в обычном режиме это такая же кнопка ввода паролей. Также пригодился RGB-светодиод на пине 21.


Когда пришло время разводить USB, я понял, что контакты никуда, кроме Type-C на плате, не выведены. Поразмыслив, я решил просто сделать переходник. Благо у меня валялись совершенно бесполезные Type-C штекеры с резистором на 56 кОм. По-русски говоря это означает, что на выход питания они не годятся (а покупались за этим давным-давно), а вот на вход работают отлично!


Что касается корпуса, он получился трехсоставным (не считая удлинителя кнопки) — основной модуль с платой закрывается двумя половинками, в него вставляется монолитный переходник. Светодиод вывел с помощью капли термоклея.


Может, не шедевр дизайна, но вполне функционально, компактно и печатается без поддержек.

За счет переходника это самостоятельное устройство вроде флешки, но при желании можно подключить через удлиняющий провод Type-C. Устройство становится еще более компактным.


И, конечно, пару слов сказать о прошивке. Все относительно стандартно — я использовал USB и USBHIDKeyboard для клавиатуры, Preferences, nvs_flash и aes для сохранения пароля зашифрованным; GyverButton — для кнопок; WebServer, WiFi, DNSServer — для странички смены паролей.

Полный листинг кода
#include <Arduino.h>
#include "USB.h"
#include "USBHIDKeyboard.h"
#include <WiFi.h>
#include <WebServer.h>
#include <DNSServer.h>
#include <Preferences.h>
#include <GyverButton.h>
#include "mbedtls/aes.h"
#include "nvs_flash.h"

// ==========================================
// НАСТРОЙКИ ПИНОВ И ЖЕЛЕЗА
// ==========================================
const int BTN_PINS[3] = {0, 6, 7};
const int GND_PINS[2] = {4, 9};
const int RGB_PIN = 21;

GButton btn1(BTN_PINS[0]);
GButton btn2(BTN_PINS[1]);
GButton btn3(BTN_PINS[2]);

USBHIDKeyboard Keyboard;
WebServer server(80);
DNSServer dnsServer;
const byte DNS_PORT = 53;
Preferences prefs;

bool isConfigMode = false;
unsigned long configStartTime = 0;

// ==========================================
// УПРАВЛЕНИЕ RGB
// ==========================================
void setRGB(uint8_t r, uint8_t g, uint8_t b) {
  neopixelWrite(RGB_PIN, r, g, b);
}

// ==========================================
// КРИПТОГРАФИЯ (AES-256 CTR)
// ==========================================
uint8_t aesKey[32];
uint8_t aesIV[16];

void initCrypto() {
  prefs.begin("crp", false); // Короткое имя пространства имен
  if (prefs.getBytesLength("key") != 32) {
    esp_fill_random(aesKey, 32);
    esp_fill_random(aesIV, 16);
    prefs.putBytes("key", aesKey, 32);
    prefs.putBytes("iv", aesIV, 16);
  } else {
    prefs.getBytes("key", aesKey, 32);
    prefs.getBytes("iv", aesIV, 16);
  }
  prefs.end();
}

void savePassword(int index, String plain) {
  if (plain.length() == 0) return;

  mbedtls_aes_context aes;
  mbedtls_aes_init(&aes);
  mbedtls_aes_setkey_enc(&aes, aesKey, 256);

  unsigned char iv_copy[16];
  memcpy(iv_copy, aesIV, 16);

  size_t nc_off = 0;
  size_t len = plain.length();
  unsigned char stream_block[16];
  unsigned char* encrypted = new unsigned char[len];

  mbedtls_aes_crypt_ctr(&aes, len, &nc_off, iv_copy, stream_block, (const unsigned char*)plain.c_str(), encrypted);
  mbedtls_aes_free(&aes);

  prefs.begin("pwd", false);
  String key = "p" + String(index);
  prefs.putBytes(key.c_str(), encrypted, len);
  prefs.end();

  delete[] encrypted;
}

String loadPassword(int index) {
  prefs.begin("pwd", true);
  String key = "p" + String(index);
  size_t len = prefs.getBytesLength(key.c_str());
  if (len == 0) {
    prefs.end();
    return ""; // Если в памяти ничего нет
  }

  unsigned char* encrypted = new unsigned char[len];
  prefs.getBytes(key.c_str(), encrypted, len);
  prefs.end();

  mbedtls_aes_context aes;
  mbedtls_aes_init(&aes);
  mbedtls_aes_setkey_enc(&aes, aesKey, 256);

  unsigned char iv_copy[16];
  memcpy(iv_copy, aesIV, 16);

  size_t nc_off = 0;
  unsigned char stream_block[16];
  unsigned char* decrypted = new unsigned char[len + 1];

  mbedtls_aes_crypt_ctr(&aes, len, &nc_off, iv_copy, stream_block, encrypted, decrypted);
  mbedtls_aes_free(&aes);

  decrypted[len] = '\0';
  String result = String((char*)decrypted);

  delete[] encrypted;
  delete[] decrypted;
  return result;
}

// ==========================================
// ВЕБ-СЕРВЕР И CAPTIVE PORTAL
// ==========================================
void handleRoot() {
  String html = R"=====(
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>Менеджер паролей</title>
<style>
  body { font-family: 'Segoe UI', Tahoma, sans-serif; background: #1a1a2e; color: #fff; padding: 20px; display: flex; justify-content: center; margin: 0;}
  .card { background: #16213e; padding: 20px; border-radius: 12px; box-shadow: 0 10px 25px rgba(0,0,0,0.8); width: 100%; max-width: 420px; }
  h2 { text-align: center; color: #e94560; margin-bottom: 20px; text-transform: uppercase; letter-spacing: 1px;}
  .group { margin-bottom: 20px; background: #0f3460; padding: 15px; border-radius: 8px; }
  .wifi-group { background: #e9456022; border: 1px solid #e94560; }
  label { display: block; margin-bottom: 8px; font-weight: bold; font-size: 14px; color: #ccc;}
  input { width: 100%; padding: 12px; margin-bottom: 12px; border: none; border-radius: 5px; box-sizing: border-box; background: #222; color: #0f0; font-family: monospace; font-size: 16px; outline: none;}
  button { width: 100%; padding: 12px; border: none; border-radius: 5px; cursor: pointer; font-weight: bold; transition: 0.2s; }
  .btn-gen { background: #e94560; color: #fff; }
  .btn-gen:hover { background: #d83a50; }
  .btn-save { background: #4caf50; color: #fff; font-size: 18px; padding: 16px; margin-top: 10px; text-transform: uppercase;}
  .btn-save:hover { background: #45a049; }
  .note { font-size: 12px; color: #888; text-align: center; margin-top: 15px; line-height: 1.5; }
</style>
<script>
  function g(id) {
    const c = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+~=";
    let p = ""; for(let i=0; i<16; i++) p += c[Math.floor(Math.random()*c.length)];
    document.getElementById(id).value = p;
  }
</script>
</head><body>
<div class="card">
  <h2>Настройки ключа</h2>
  <form action="/save" method="POST">

    <div class='group wifi-group'>
      <label> ПАРОЛЬ ОТ ЭТОЙ WI-FI СЕТИ</label>
      <input type='text' name='p0' id='p0' placeholder='Оставьте пустым для сохранения текущего'>
      <div style="font-size:11px; color:#aaa; margin-top:-5px;">Минимум 8 символов.</div>
    </div>
)=====";

  for (int i = 1; i <= 3; i++) {
    html += "<div class='group'><label>КНОПКА " + String(i) + "</label>";
    html += "<input type='text' name='p" + String(i) + "' id='p" + String(i) + "' placeholder='Введите новый или оставьте пустым'>";
    html += "<button type='button' class='btn-gen' onclick=\"g('p" + String(i) + "')\">Сгенерировать</button></div>";
  }

  html += R"=====(
    <button type="submit" class="btn-save">Сохранить в память</button>
  </form>
  <div class="note">⚠️ Текущие пароли скрыты.</div>
</div></body></html>
  )=====";
  server.send(200, "text/html", html);
}

void handleSave() {
  String p0 = server.arg("p0");
  String p1 = server.arg("p1");
  String p2 = server.arg("p2");
  String p3 = server.arg("p3");

  if (p0.length() >= 8) savePassword(0, p0);
  if (p1.length() > 0) savePassword(1, p1);
  if (p2.length() > 0) savePassword(2, p2);
  if (p3.length() > 0) savePassword(3, p3);

  setRGB(100, 80, 0);

  String html = "<!DOCTYPE html><html><body style='background:#1a1a2e; color:#0f0; font-family:sans-serif; text-align:center; padding-top:50px;'>";
  html += "<h2>Успешно сохранено!</h2><p>Устройство перезагружается...</p></body></html>";

  server.send(200, "text/html", html);
  delay(1500);
  setRGB(0, 0, 0);
  ESP.restart();
}

void handleNotFound() {
  server.sendHeader("Location", String("http://") + WiFi.softAPIP().toString(), true);
  server.send(302, "text/plain", "");
}

// ==========================================
// СТАРТ УСТРОЙСТВА
// ==========================================
void setup() {
  // На всякий случай оставляем защиту от битой флешки
  esp_err_t err = nvs_flash_init();
  if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
    nvs_flash_erase();
    nvs_flash_init();
  }

  for (int i = 0; i < 2; i++) {
    pinMode(GND_PINS[i], OUTPUT);
    digitalWrite(GND_PINS[i], LOW);
  }

  setRGB(50, 0, 100);
  delay(400);
  setRGB(0, 0, 0);

  btn1.setTimeout(3000);
  btn2.setTimeout(3000);
  btn3.setTimeout(3000);

  initCrypto();
  Keyboard.begin();
  USB.productName("PassKey HID"); // Заставляем ПК увидеть новое устройство
  USB.manufacturerName("WireRod");
  USB.begin();
}
// ==========================================
// ГЛАВНЫЙ ЦИКЛ
// ==========================================
void loop() {
  if (isConfigMode) {
    dnsServer.processNextRequest();
    server.handleClient();
    if (millis() - configStartTime > 300000) ESP.restart();
    return;
  }

  btn1.tick();
  btn2.tick();
  btn3.tick();

  bool c1 = btn1.isClick();
  bool c2 = btn2.isClick();
  bool c3 = btn3.isClick();

  // --- КОРОТКИЕ НАЖАТИЯ (Ввод пароля) ---
  if (c1 || c2 || c3) {
    setRGB(0, 100, 0);

    String p = "";
    if (c1) p = loadPassword(1);
    else if (c2) p = loadPassword(2);
    else if (c3) p = loadPassword(3);

    if (p == "") {
      Keyboard.print("[ERROR: MEMORY IS EMPTY]");
    } else {
      Keyboard.print(p.c_str());
    }

    delay(50);
    setRGB(0, 0, 0);
  }

  bool h1 = btn1.isHold();
  bool h2 = btn2.isHold();
  bool h3 = btn3.isHold();

  // --- ДОЛГОЕ НАЖАТИЕ ---
  if (h1 || h2 || h3) {

    // ПРОВЕРКА НА ПАНИК-КНОПКУ (Зажаты ли ВСЕ ТРИ кнопки физически?)
    if (btn1.state() && btn2.state() && btn3.state()) {

      setRGB(255, 0, 0); // Врубаем КРАСНЫЙ

      // Полностью форматируем раздел с паролями
      prefs.begin("pwd", false);
      prefs.clear();
      prefs.end();

      // И удаляем крипто-ключи (при следующей загрузке сгенерируются новые)
      prefs.begin("crp", false);
      prefs.clear();
      prefs.end();

      delay(2000); // Горим красным 2 секунды, чтобы юзер понял, что всё удалено
      setRGB(0, 0, 0);
      ESP.restart(); // Перезагружаемся в чистом виде

    } else {

      // ОБЫЧНЫЙ РЕЖИМ WI-FI (Зажата одна кнопка)
      setRGB(0, 50, 150);

      String apPass = loadPassword(0);
      if (apPass.length() < 8) apPass = "12345678";

      WiFi.softAP("MyPassKey", apPass.c_str());
      dnsServer.start(DNS_PORT, "*", WiFi.softAPIP());

      server.on("/", handleRoot);
      server.on("/save", HTTP_POST, handleSave);
      server.onNotFound(handleNotFound);
      server.begin();

      isConfigMode = true;
      configStartTime = millis();
    }
  }
}


Для чего DNSServer, спросите вы? Как оказалось, можно упростить вход на страничку паролей, если перенаправлять запросы ОС на специализированный DNS-сервер, как это делают всякие роутеры. Теперь не нужно вбивать айпишник в адресную строку, можно просто нажать на всплывающее предупреждение. Очень удобно.


Сама страничка содержит поля смены пароля Wi-Fi и пользовательских учетных данных.



Реализован режим сброса — зажать все три кнопки. Пароль WiFi при этом сбрасывается на стандартный, а остальные стираются из памяти.

За счет индикации взаимодействие с устройством становится более интуитивным. Подключение устройства к ПК.


Ввод пароля.


При активации смены пароля светодиод начинает постоянно гореть синим.


В принципе, и я, и заказчик устройством остались довольны. Думаю сделать нечто похожее и себе, но с биометрической авторизацией. В текущем виде устройство чуть получше листка с паролем, наклеенным на монитор. Полный код и файлы для печати (и для редактирования) доступны в репозитории.
Добавить в избранное
+80 +95
свернутьразвернуть
Комментарии (60)
RSS
+
avatar
+6
  • E155-2
  • 25 августа 2026, 22:30
недостаток HID ввода это невозможность учесть раскладку клавиатуры. Англоязычным можно позавиидовать за то что у них нет 2-3, а то и более раскладок. Я решил проблему с раскладкой с помощь. автоввода KeepassXC, он вводит строку, а не эмулирует нажатие клавиш
+
avatar
+2
  • xNIXx
  • 26 августа 2026, 20:07
В винде вроде бы можно переключать по комбинации клавиш на нужный язык. Просто посылаешь ее вначале…
Себе хотел сделать, но неудобств совершенно не испытываю, обычно раскладка нужная.
+
avatar
0
  • demonk
  • 28 августа 2026, 11:57
Только комбинация клавиш у всех разная
+
avatar
+1
  • xNIXx
  • 28 августа 2026, 13:54
И ээээ… в чём проблема :)?
+
avatar
0
  • demonk
  • 28 августа 2026, 14:10
Ну дык в конфигураторе придется добавлять настройку комбинации переключения языка, со всеми возможными сочетаниями этих Ctrl-Alt-Shift-Caps-Tab-Win, при том что просто ввести их с клавиатуры нельзя. Что чутка посложнее простой строки ввода. Кстати, недавно вообще видел клаву с отдельными кнопами РУС и ЛАТ, прям как в старину.
+
avatar
+2
  • Qurdi
  • 28 августа 2026, 15:13
Alt+код символа на цифровой клавиатуре можно
+
avatar
0
  • demonk
  • 28 августа 2026, 15:31
Не, так можно только символы ввести, всяческие служебные клавиши и их сочетания не получится. Разве что подсмотреть в справочнике скан-коды и описать их каким типа скриптовым языком.
+
avatar
0
  • Qurdi
  • 28 августа 2026, 16:00
А зачем для ввода пароля служебные клавиши и их сочетания?
+
avatar
0
  • demonk
  • 28 августа 2026, 16:29
Ну вон же, диалог начался с упоминания, что перед вводом пароля не помешало бы сначала включить нужную раскладку клавиатуры. Да и сами пароли бывают смесью латиницы с кириллицей, надо еще и в процессе ввода переключать.
+
avatar
0
  • Qurdi
  • 07 сентября 2026, 12:03
Зачем переключать, если сразу код символа можно?
+
avatar
0
по моим наблюдениям меняют комбинации клавиш меньше 1% пользователей
подавляющее большинство вообще не подозревает что это можно сделать
+
avatar
+2
  • demonk
  • 28 августа 2026, 15:39
Мне достаточно одного меня.
Еще в досе привык к Ctrl-Shift и если попадаю за чужой комп — то сначала матерюсь я, а потом хозяин компа, когда не может переключить :)
+
avatar
+1
  • Opostrof
  • 02 сентября 2026, 12:53
Не знаю как кто, но комбинацию Alt+Shift считаю самым порочным выкидышем мысли для смены языка. Не счесть сколько программ по той или иной причине ловили Alt отдельно и начиналась дичь с меню.
+
avatar
+3
  • andy077
  • 25 августа 2026, 23:38
Ни один безопасный компутер вашу феньку в себя не допустит.
+
avatar
+11
  • Megalan
  • 26 августа 2026, 02:38
Если в DLP софте все USB устройства безоговорочно в режиме whitelist — вероятно. Во всех остальных случаях девайс ничем не отличается от обыкновенной usb клавиатуры.

Но начать надо с того, что девайс по определению и не ставит под собой цель работы в DLP среде иначе бы он как минимум ставился бы в разрыв с реальной клавиатурой и мимикрировал под ее PID/VID.
+
avatar
+6
  • Latte
  • 25 августа 2026, 23:40
Также заказчик попросил, чтобы его пароли не лежали в открытом виде. Последняя просьба прозвучала немного странно, ибо нажатие кнопки вводит пароль в совершенно открытом виде…
Один пароль не дискредитирует все хранилище в случае утери сего девайса. Но для этого надо заморачиваться с eFuse, как минимум, а в такой реализации, как я понял, все сливается с флешки обычным программатором вместе с ключом. Так уж аес тут реально без толку, только еспшку греть.
Думаю сделать нечто похожее и себе, но с биометрической авторизацией.
Может, лучше юбикей… Можно еще попридираться к коду в целом, но тут смотря что понимать под коммерцией — на деле оказывается, что это единичный заказ на одного клиента.
+
avatar
+4
  • Omnicorn
  • 26 августа 2026, 00:01
Но для этого надо заморачиваться с eFuse, как минимум, а в такой реализации, как я понял, все сливается с флешки обычным программатором вместе с ключом.
В целом, да. Но технически пароль все же хранится зашифрованным, верно? :)
Может, лучше юбикей…
Это не столь интересно. Я тут почитал про сенсор отпечатков, и, оказывается, для защищенной реализации нужно пилить свой парсер отпечатков, так как дешевые датчики работают по уморительно незащищенному протоколу. Так что проект получится занимательный, с фильтрами Габара, может полярным FFT, или нейронкой.
Можно еще попридираться к коду в целом, но тут смотря что понимать под коммерцией — на деле оказывается, что это единичный заказ на одного клиента.
В любом случае заказ есть заказ. А код да, не идеален. Но я решил оставить AES как заготовку на будущее. Было интересно его потыкать в коде.
+
avatar
+2
  • nsn
  • 26 августа 2026, 00:04
Один пароль не дискредитирует все хранилище в случае утери сего девайса.
Что-то непонятно, какое всё хранилище?
+
avatar
0
  • Latte
  • 26 августа 2026, 08:49
Содержимое структуры Preferences. При копировании из Keepass пароль так то тоже копируется в буфер обмена в открытом виде, что не мешает программе защищать (насколько это возможно) остальное содержимое базы паролей.
+
avatar
+2
  • nsn
  • 26 августа 2026, 10:19
Содержимое структуры Preferences.
Но ведь там ничего нет, кроме выдаваемых по кнопкам паролей и случайных ключей, используемых для шифрования.

При копировании из Keepass пароль так то тоже копируется в буфер обмена в открытом виде.
Keepass пароли в открытом виде не выдаёт просто по механическому запросу, без предварительной разблокировки хранилища.
+
avatar
+4
  • Zolg
  • 26 августа 2026, 00:23
если нужна хоть сколько-то безопасная аутентификация, то github.com/polhenarejos/pico-fido (оно же www.picokeys.com/)
Там тоже не все идеально, но во-первых это аппаратные ограничения, от которых без использования специализированных чипов не избавиться (да и с использованием — не на 100%), во-вторых все же ГОРАЗДО безопасней сабжового велосипеда
+
avatar
+4
  • Omnicorn
  • 26 августа 2026, 00:49
Да я и не заявлял какую-то особую безопасность. Вставляешь прибор — нажимаешь на кнопку — вводится пароль. Тут уж вопрос, попадет она в чужие руки или нет. Она не безопаснее ключа от квартиры. По-моему, я все четко описал в статье.
Последняя просьба прозвучала немного странно, ибо нажатие кнопки вводит пароль в совершенно открытом виде…
Что касается вашей ссылки — это скорее не хранилище паролей, а аутентификатор. И работает только с теми, кто поддерживает такую же технологию. И для настройки устройства нужно ставить специальный софт. Решение неплохое, но явно не универсальное.
+
avatar
+2
Хорошие были проекты у него: fido, hsm, pgp, но в 7.х версии бортанул многих, убрав сборки, сделав платный прошивальщик, а тем, кто шил с секьюр бутом/локом вообще не позавидуешь.
Потом появился сайд проект github.com/librekeys/picoforge, который поддерживает оригинальный pico-fido и слоп-кодженную альтернативу github.com/TheMaxMur/RS-Key
+
avatar
0
  • vedroid
  • 26 августа 2026, 00:32
Я не понял в чем здесь смысл шифрования если сам ключ шифрования храниться на самом устройстве: prefs.putBytes(«key», aesKey, 32); и даже совсем чуть подкованный технарь-любитель достанет ключ из «prefs». По хорошему, ваша биометрия должна преобразовываться в ключ шифрования с помощью специальной key derivation функции (по аналогии с обычной key derivation функцией для преобразования мастер-пароля в ключ шифрования), а сам ключ шифрования нигде не должен сохранятся. Эти борды ведь вроде поддерживают eFuse, вот там и нужно было инициализировать ключ шифрования (но даже так, eFuse форенсики прочитают если нужно будет, но любители нет).
+
avatar
+10
Я не понял в чем здесь смысл шифрования если сам ключ шифрования храниться на самом устройстве:
да вопрос то даже не в этом, а в том что устройство, как бы ни хранило и как бы ни шифровало пароль — отдаст его без всяких вопросов просто по нажатию кнопки.
+
avatar
+5
  • kvarkk
  • 26 августа 2026, 12:06
Если вы храните пароли дома в блокноте, то он тоже отдаст их без вопросов, когда попадет в чьи-то руки. Для дома такой девайс вполне годен, ничем не хуже блокнота.
+
avatar
+6
это понятно. непонятно зачем тут шифрование, если для доступа к паролю достаточно просто нажать кнопку на устройстве, и оно само его выплюнет в порт.
+
avatar
0
У программистов есть правило — никогда не писать криптографию самому, а использовать готовые проверенные библиотеки.
Надо было не изобретать велосипед, а сказать клиенту чтобы купил какой-нибудь yubikey.
+
avatar
0
  • vedroid
  • 26 августа 2026, 01:01
Здесь не изобретаются алгоритмы шифрования, но как раз используются готовые. Другое дело что оно — готовое библиотечное шифрование, здесь используется таким образом, что становится бессмысленным.
+
avatar
+8
  • ploop
  • 26 августа 2026, 08:32
никогда не писать криптографию самому, а использовать готовые проверенные библиотеки.
… которые написали программисты, которые никогда не писали криптографию сами, а использовали готовые проверенные библиотеки :)
+
avatar
+7
  • Qurdi
  • 26 августа 2026, 09:20
А потом в проверенных библиотеках находят уязвимость, и в новостях появляются статьи, как программисты с проверенными библиотеками в очередной раз облажались
+
avatar
+2
  • Latte
  • 26 августа 2026, 09:24
Если результат будет тем же, то зачем платить больше? Задействование сторонней либы занимает меньшей сил, и проверяет ее на вшивость народу больше джуна Ивана из соседнего отдела. А уязвимости нынче находят во всем подряд, электронный послушный батрак стоит копейки.
+
avatar
+2
  • Qurdi
  • 26 августа 2026, 09:31
Ещё и для работодателя отмазка удобная — взломали, а разработчики не виноваты, они готовую проверенную библиотеку использовали.
+
avatar
0
Чтобы понять рекурсию, надо понять рекурсию.
+
avatar
-1
  • valerak2
  • 26 августа 2026, 07:31
неплохо вполне
+
avatar
0
ИМХО всё же логичнее выглядит девайс с экраном, хранение/отображение/выбор/ввод связки логин+пароль и доступ к девайсу по паролю/отпечатку на случай утери. ну то есть чтобы просто от мамкиных хакеров защититься.
+
avatar
+2
  • Latte
  • 26 августа 2026, 09:12
Можно просто пинкодом на трех кнопках защититься, экран тут без надобности.
+
avatar
+2
экран для удобства. может же быть больше трёх паролей у человека.
+
avatar
+4
  • aliex
  • 26 августа 2026, 10:21
От задач зависит. А задача может быть, например, «да задолбали со своим паролем на каждый чих, хочу одной кнопкой». Банальный пример — работа из дому, рабочий бук требует ввод пароля на что попало. То, что на буке — мониторится, по полиси хранить пароли нельзя, каждый раз вводить руками, сидя дома — тупо, прятаться не от кого.
+
avatar
0
Офигенно использовать ESP с закрытыми модулями wifi/bt для чего-то безопасного )))))
Какие там закладки китайцы поставили — только они и знают.

Про самобытныю криптографию я вообще молчу.

P.S. кто не знает — не смотря на то, что IDF как-бы открытый и barebone вроде-бы даже доступен, модули ядер wifi/bt закрытые и что там и как сделано — нигде не описано и не документировано. Те оно может сливать что-то по-получению команды извне, например.
+
avatar
+1
  • Qurdi
  • 26 августа 2026, 09:29
Найти открытый модуль wifi/bt сама по себе не очень тривиальная задача. А тот, с прошивкой которого проводился хоть какой-то авторитетный аудит безопасности, по моему вообще нереально.
+
avatar
+3
  • aliex
  • 26 августа 2026, 10:23
Когда говорим о безопасности — в первую голову выясняем, от кого защищаемся, мнится мне, что в данном случае о китайцах никто особо не беспокоился…
+
avatar
0
  • vovanium
  • 28 августа 2026, 09:52
Вы так пишете, вроде этим девайсом вводят коды запуска ядерных ракет :)
+
avatar
+6
  • 00svd00
  • 26 августа 2026, 11:42
Хех. Года три тому сделал себе почти такой же
Только эмулирует BT клаву — ибо проще и портов на ноуте не напасёшься. Ну и всякие доп фишечки типа даблтапа по намлоку раз в 5 минут, ввода любого текста через веб форму и т.п.
+
avatar
+2
  • aliex
  • 26 августа 2026, 12:13
У меня под подобное заначена esp32 с тачпадом — там, конечно, в планах полноценный пассворд менеджер с поддержкой какого-нибудь из браузерных расширений…
+
avatar
0
  • 00svd00
  • 26 августа 2026, 12:23
С тачпадом через PS/2 или через родные тач сенсоры(ссылки на международный алик в РФ не открываются)?
Я поначалу хотел заморочиться и добавить эмуляцию USB через микрушку ps/2->USB hid, но потом решил что ну его нафиг
А так двух кнопок в целом хватает. Одна листает пароли, другая вводит. Все настройки через вебморду в любом случае
+
avatar
0
  • aliex
  • 26 августа 2026, 13:09
Ловите российский: https://aliexpress.ru/item/1005009263299221.html
Тач чисто под управление самим девайсом, никаких ps/2.
Display size 1.47inch
Resolution 172 × 320 pixels
Display chip JD9853
Touch chip AXS5106L
Display Interface 4-wire SPI
Touch interface I2C
Во-первых, я люблю удобные интерфейсы, так что кнопок надо было бы минимум 4 — вперёд/назад/ок/cancel. Во-вторых, в варианте тачскрина мне не нужно вообще ничего паять — я просто беру эту железку, делаю ей заднюю крышку — и всё красиво.
+
avatar
0
  • 00svd00
  • 26 августа 2026, 13:26
А, не с тачпадо а с тачскрином? Норм тема, да. Но физкнопки ИМХО всё таки нужны, т.к. лично я обычно пользуюсь одной рукой и наощупь, т.к. уже выучил, какой пароль под каким номером лежит. С тачскрином так не выйдет(но в любом случае две кнопки у железки есть)
А паять всё равно придётся, аккум далеко не лишний, а он автоматом тянет за собой разрыватель питания и пару резисторов делителя для измерения бортового напряжения.
+
avatar
0
  • aliex
  • 26 августа 2026, 14:27
Не понял, зачем там аккум? Оно по определению имеет смысл только если подключено по USB.

Насчёт номеров паролей — в общем случае оно должно работать как нормальный password manager, то есть ему скормили ключ (url для сайтов, к примеру, или имя сервера) — оно его показало и после подтверждения отправило пароль. Всё остальное — экзотические случаи, там автопилот без надобности.
+
avatar
0
  • 00svd00
  • 26 августа 2026, 14:37
Не понял, зачем там аккум? Оно по определению имеет смысл только если подключено по USB.
Если эмулировать юсб хид — да. Но опять, КМК блюпуп удобнее.
+
avatar
0
  • aliex
  • 26 августа 2026, 14:39
А! Не, у меня стационары, там блютуса нет, да и не согласен я насчёт удобства.
+
avatar
0
Только эмулирует BT клаву — ибо проще и портов на ноуте не напасёшься. Ну и всякие доп фишечки типа даблтапа по намлоку раз в 5 минут, ввода любого текста через веб форму и т.п.
проект окрытый у вас или закрытый?
+
avatar
0
  • 00svd00
  • 26 августа 2026, 14:36
Проект не доехал до гитхаба потому что я заленился расписывать о том, что блютус дырявый, пароли в открытом виде, нот э сесурити девайс, никакой ответственности, на ваш риск, вот это вот всё. А вас там что-то конкретное интересует?
+
avatar
0
Эмуляция бт клавиатуры. Остальное есть от предыдущих проектов.
+
avatar
+2
  • 00svd00
  • 26 августа 2026, 16:16
Сорцов в моменте под рукой нет — остались на другом компе. Но ЕМНИП я тупо заюзал эту либу
github.com/T-vK/ESP32-BLE-Keyboard
Точнее какой-то из форков, т.е. оригинал очень древний плохо собирался
+
avatar
0
Спасибо.
+
avatar
+5
рекоммендую ещё похожий проект blue_keyboard — связка виртуальной клавы с кипасс менеджером на мобиле по блютусу.
+
avatar
0
  • islera
  • 26 августа 2026, 23:13
А телефон через блютуз эмулировать клавиатуру не может? Подошёл с телефоном к компу с включенным блютусом — компьютер разблокировали, нужен другой пароль — на компе список логинов, при нажатии на которые через эмулируемую хитклаву в комп отправляется нужный пароль. Список на экране телефона можно сделать любой, паять ничего не нужно…
+
avatar
0
  • aliex
  • 27 августа 2026, 01:22
С рутом — может
+
avatar
0
  • Nuts_
  • 31 августа 2026, 15:00
по изначальному ТЗ это должна быть скорее pastilda но получилось скорее rubber duck с кнопками
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.