Сервіс для передачі секретів у разі форсмажору

💡 Усі статті, обговорення, новини про продукти — в одному місці. Приєднуйтесь до Product спільноти!

Привіт!

В рамках навчання ми вже багато років проводимо стажування для студентів. Часом проєкти цікаві з технічної точки зору, але звучать не дуже: там зробили кастомного чат-бота, там якусь незрозумілу новачку інтеграцію... Я завжди хотів створити в рамках навчання якийсь прикольний та унікальний проєкт.

І от одного дня на думку спала незвичайна ідея

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

Мені певний час довелось подорожувати окремо від родини і я задумався: а що буде, якщо зі мною щось трапиться?

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

Більш того я би хотів, щоб всі мої секретні дані родина отримала лише у випадку форс-мажору. Немає чого дивитись на мої крипто баланси без необхідності 🙂

Я почав роздумувати над сервісом, що буде надійно зберігати мої секрети до моменту Х і в потрібний момент відправить їх зазначеним адресам.

Для себе я виділив певні критерії та функціонал, як для людини, яка сама буде користувачем:

  • Надійне шифрування та зберігання всіх даних
  • Гнучке налаштування правил та умов відправки
  • Зручний механізм передачі моєї секретної «посилки» адресатам
  • Мінімізувати роботу з криптографією для користувачів — сервіс має бути зрозумілим людям без ІТ бекграунду.

Після плідного спілкування з різними Ai-шними інструментами за 3 години я отримав MVP і розуміння, що Ai замінить програмістів ще не скоро :)

Отриманий каркас проєкту було взято за основу і вже вручну ми з командою студентів почали його дороблювати під наше бачення.

Як працює сервіс?

Сервіс назвали Parcelr.com. З його допомогою ви можете створити те, що ми назвали цифровою посилкою (parcel). Посилка має список отримувачів, дедлайн для відправки та сам секретний контент: набір файлів та/або текстове повідомлення.

Автор посилки має придумати для її отримувача набір питань та задати для них відповіді. Ідея така, щоб вигадати питання, відповіді на які знає лише отримувач посилки і це не складно, якщо отримувач близька вам людина: імена домашніх улюбленців, дівоче прізвище тещі, вигадати таких питань можна багато. Якщо з фантазією погано, то можна використати звичайний пароль.

Далі на основі заданих відповідей на стороні клієнта генерується ключ для шифрування і весь контент посилки шифрується цим ключем за допомогою стандарту OpenPGP. Все відбувається на стороні клієнта, ключі для шифрування на сервер ні в якому разі не передаються.

Після шифрування посилка завантажується на сервер і відправляється на зберігання в AWS S3. Метадані посилки такі, як список отримувачів, час відправки тощо можна змінювати в той час, як сама посилка після створення залишається незмінною.

Що відбувається, коли настав дедлайн?

По перше, у власника посилки є можливість продовжити час відправки. Це можна зробити в онлайн кабінеті, або за допомогою спеціального лінку, якщо це треба зробити швидко без логіну. Така собі кнопка «В мене все ОК, не відправляй».

При наближенні дедлайну власник посилки отримає нагадування, щоб мати можливість змінити час її відправки або взагалі відмінити відправку.

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

Статус посилки (відправлена, прочитана тощо) можна відслідковувати в кабінеті користувача.

Враховуючи, що email — не самий надійний спосіб доставки, ми додали інтеграції з Telegram та WhatsApp (остання ще тестується). Щоб адресат не пропустив свою посилку, ви заздалегідь можете дати йому посилання, щоб підписатись на бота, а бот при настанні дедлайну відправить посилку додатково до відправки на пошту через месенджер.

Стек проєкту:

  • Java 21
  • Spring Boot, Spring Data, Spring Security
  • Bootstrap + Thymeleaf + vanilla JS
  • PostgreSQL
  • Redis
  • AWS S3, AWS KMS
  • Heroku.

Криптографія

Тут вирішили не вигадувати велосипед і взяли готові популярні JS бібліотеки. Ключ для шифрування створюється із відповідей за допомогою алгоритму PBKDF2. Сама посилка шифрується за стандартом OpenPGP з використанням AES-256.

Що далі?

Враховуючи, що метою продукту є отримання різноманітного досвіду, то ми додали наступний функціонал:

  • Питання для відкриття посилок шифруються на стороні сервера за допомогою AWS KMS.
  • Платні підписки.
  • Отримали досвід використання Docker для локального розгортання та тестування.
  • Розгорнули продукт на Heroku.

З недоліків: UI зроблений на звичайному Bootstrap, виглядає зносно, але є над чим працювати.

Проєкт стане одним з тих, що ми будемо використовувати як майданчик для підвищення кваліфікації студентів. Кількість можливих нових функцій та корисних інтеграцій тут безмежна, тому будемо розвивати ідею.

Найважливіші задачі:

  • Новий дизайн
  • Перехід від Thymeleaf та чистого JS до React
  • Відправка посилок через WhatsApp та SMS
  • Більше тестів.

Особисто я вирішив свою проблему і моя посилочка для родини на випадок «якщо що» надійно зберігається за допомогою даного сервісу. Для мене — це основна ознака якості продукту. Для вас — підказка, де шукати master key від моїх криптогаманців 🙂

Будемо з командою вдячні за будь який фідбек, критику та побажання щодо функціоналу та ідеї вцілому, а також з радістю відповім на всі питання!

👍ПодобаєтьсяСподобалось8
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Я думав буде щось інноваційне наприклад про блокчейн з шифруванням під виглядом NFT. Але все так виявилось дуже традиційно.

Блокчейн — це вже вчорашній день, треба з Ai і побільше)

А навіщо взагалі шифрування? Якщо ви робите

Ключ для шифрування створюється із відповідей за допомогою алгоритму PBKDF2

то ентопія ключу дорівнює ентропії даних на основі яких він генерувався. А так як це відповіді на питання, причому такі щоб інші люди здогадались, а не тільки ви, то всі ваші шифри зламаються за пару хвилин перебором по словнику.

Банальний глобальний ключ схований в енваронменті був би тупо надійніше, бо треба було й базу зломати й до енвайронменту дістатись. В вашому випадку достатньо лише базу зламати.

Використовувати пароль замість відповідей, пароль передавати офлайн — в цілому робоча схема. Але ж не давати можливість людині ввести пароль зі словаря. Але забавно читати про те як ви робите акцент на безпеці й така лажа прямо з порогу.

А як відрізнити справжній «форс-мажор» від спроби викрасти секрети?

nvm, я спочатку подумав що це рішення щоб зашарити всі паролі якщо я помру, але я не знаю коли саме це станеться.
У вас сервіс для тих у кого плани більш конкретні.

Bitwarden предлагает такую фичу.
указываешь другого пользователя сервиса и время задержки.

В случае чего, тот другой может попросить доступ к твоим паролям. Но получит его только спустя время, которое ты сам настроил.

Таким образом, раньше времени не залезет никто, ты увидишь запрос и кансельнешь его .... ну или в худшем случае уже и не кансельнешь )

Ідеальний сервер щоб красти персональні дані... Шифрування в JS? Агінь! Інфостілер краде ключа та привіт паролям ;)

Атака номер два. Фішинговий email для отримувача, потім трохи інший для власника, щоб відбулася відправка. Далі справа техніки ;)

Наступні розкривати не буду ;)

Как раз то, и сделанное правильно. Кейс «отправь васе такие то данные, а пете такие то» покрывается документом с называнием «прочитать когда я двину копыта». Или банальными емейлами в черновиках, в которых все уже есть — просто надо отправить. И скорей всего можно автоматизацию прикрутить, если заморочиться.

То есть вы предлагаете хранить пароли и сиды от кошельков в черновиках Gmail?)

Даже так это в разы секурней и надежней левого сервиса от непонятно кого. Но можно и по другому.

Я бы не доверил секреты стороннему сервису без аудитов безопасности

Я тоже. Мы поэтому делали криптографию максимально простой на базе проверенных библиотек. Аудит = глянуть 20-30 строк JS кода.

а можна десь на ці 20-30 строк кода подивитись?

Я можливо не бачу щось дуже важливе, але:

1. ваш алгоритм формування ключа не PBKDF2(passphrase), а ARGON2(PBKDF2(passphrase)). Навіщо вам PBKDF2 не зрозуміло, ARGON2 повинно бути достатньо: github.com/...​.0/src/type/s2k/argon2.js
2. deriveKeyFromPassword — функція формування ключа, розмір ключа та кількість інтерацій — константи, якщо ви, наприклад, змінете кількість ітерацій з 1000 на 1001 розшифрувати існуючі данні у базі данних стане більше неможливо. Дивиться на те, що таке crypto agility: en.wikipedia.org/...​iki/Cryptographic_agility
3. Також не зрозуміла імлементація generateRandomString, повинно бути достатньо: crypto.randomBytes(my_salt_size), якщо треба в читабельному виді то base64(crypto.randomBytes(my_salt_size))
4. openpgpjs підтримує 3 режима шифрування AES: eax, ecb та gcm, в якому саме режимі ви шифруєту ващі данні? github.com/...​/v6.1.0/src/enums.js#L164
5. не кріпто, але не зрозуміло навіщо ви zip-єте інпут, якщо openpgp.encrypt робить це за вас: github.com/...​/main/src/message.js#L537

Ще трошки про довіру вашому сервісу:

1. Якщо користуватися вашим сервісом, то тільки у варіанті з паролем. Питання, відповіді на які ви пропонуєте вгадати отримувачу повідомлення, це дуже небезпечний засіб для формування ключа шифрування, тому що відповіді на них можна знайти в соціальних мережах, або через фішинг. Питання та контактна інформаця одержувача пакету зберігаються у відкртому для вас виді, тому вам, або тому хто бачить снепшот вашої бази данних буде легко знайти на них відповідь. Кількість правильних відповідій на питання не дуже велика, кількість спроб розшиврувати повідомлення не обмежена.

2. Ви пропонуєте користувачу передавати родині паролі від банкінгу, зазвичай на важливих єккаунтах встановлено 2FA, пароль не допоможе якщо 2FA не вимкнути заздалегідь, що є дуже небезпечною практикою. Ваш сервіс заохочує користувача вимкнути 2FA бо інакше у повідомленні немає сенсу.

3. У повідомленні яке надсилає ваш сервіс немає криптографічного підтверження авторства, отрумувач не знає хто саме надіслав це дуже важливе повідомлення, оригінальний відпарвник, рандомний скамер, або китайське кдб.

Дякую за розгорнутий відгук!

1. А звідки ARGON2 взявся?
2. Не будемо міняти)
3. Наша реалізація на пару рядків складніша, але то результат того, що код писати бекендери
4. Дефолтний CFB
5. Щоб адресат отримав посилку в одному ZIP файлі, так тут варто openpgp.enums.compression.zlib прибрати, він зайвий

Щодо зауважень до довіри: взяли в роботу, будемо покращувати сервіс в йьому напрямку.

А звідки ARGON2 взявся?

я надав лінк у моєму поперодньому повідомленні, ваш код я не дебажив, але дивлячісь на параметри ви будете формувати ключ за допомогою ARGON2 ось тут
github.com/...​ypted_session_key.js#L207

можливо ви збиралися робити encrypt трошки по іншому

const encrypted = await openpgp.encrypt({
            message,
            encryptionKeys: [encryptionKey],  <<<--- у вашому коді це passwords
            format: "binary",

в загалі не дуже зрозуміло навіщо ви використовуєте openpgp, есе що вам треба це зашифрувати AES-ом ваш message з ключом яки ви вже знегерили та IV якій теж дуже легко зненерити

Не будемо міняти

у вас данні повинні зберігаютись роками, модливо десятиріччами, якщо kdf функція або її параметри буде визнано не секрьюрними, наприклад nist, вам доведеться щось з цим робити, якщо ваш код crypto agile, як наприклад openpgpjs, якій ви використовуєте, то пофіксити це буде на багато легше

Дефолтний CFB

AES-ECB не забезбечує конфеденціальність, оскільки ви шифруєте на клієнті, конфіденціальність важлива, дивитись на AES-GCM. Будьте дуже уважні з nonce, пара ключ шифрування + nonce пиванна бути завжди унікальною

Наша реалізація на пару рядків складніша

ваша реализаця також має менше ніж 2^96 можливих унікальних значень, коли мала б мати 2^128

Чудова ідея. Чи є уже клієнти?)

Наскільки довго прослужить ваш сервіс і що станеться, коли захочете вимкнути сервери?

Є пару ідей на цей випадок, поки що думаємо яку краще реалізувати.

гугл пошта, закриптований лист з відтермінуванням відправки, в якому запаролений архів, пароль від якого знає лише довірена особа.
Не дякуйте

Ну або OpenSSL/GnuPG + CRON... але то все для продвинутої аудиторії. А наша ЦА — прості юзери)

будь які цінні активи потребують «юрідичного супровіду»... в твоєму випадку юрідичні ризики, це те, що хоронить цю ідєю «як бізнес». Як навчання, пет-проджек, будь яка реальна робота над задачами, розв’язання технічних проблем плюс до твого досвіду та резюме. )

Я про це думав. Сервіс не вирішує питання рівня «передати права власності на нерухомість», він працює з цифровиіи активами. Тому 99% юридичних питань можна закрити на рівні «Terms and conditions». Але поки що — це майданчик для отримання досвіду студентами.

А чому просто не використати delayed email / post ?

delayed email

не вирішує питання безпеки даних. Тут фішка в простому для користувача шифруванні даних без необхідності розбиратись з криптографією та менеджети ключі.

не вирішує питання безпеки даних.

А як нікому не відомий сервіс, для сбору паролів це вирішить?

без необхідності розбиратись з криптографією та менеджети ключі.
Несите ваши денежки — иначе быть беде!

Як вирішує написано в статті. Як перевірити, що ми не збираємо паролі для своїх цілей — достатньо сходити в JS код фронтенду, ми спеціально його писали простим на чистому JS без мініфікації, щоб спростити аудит.

Тут фішка в простому для користувача шифруванні даних без необхідності розбиратись з криптографією та менеджети ключі.
достатньо сходити в JS код фронтенду

Тобто треба лише самостійно зробити секуртіті аудит JS, а PhD у секуріті не потрібно?

А наша ЦА — прості юзери)

Ага

Скажімо так, кому цікаво, той може зробити аудит 30 рядків JS коду, де реалізовано client side шифрування без PhD. Ми не писали криптографію самостійно, там під капотом OpenPGP.js і ще пара ліб. А пояснити надійність сервісу для простих корустувачів, то більше задача маркетингова.

А пояснити надійність сервісу для простих корустувачів, то більше задача маркетингова.

«Відстаньте, я не тактик, я — стратег»

Критикувати я теж вмію) Як ви думаєте можна підтвердити надійність сервісу для людей, які не мають технічного бекграунду?

Ви пропонуєте людям робити те саме, що прононують інтернет шахраї — вантажити свої секрети «кудись в інтернет». Буквально, це навіть не метафора.

Як ви думаєте можна підтвердити надійність сервісу для людей, які не мають технічного бекграунду?

Ніяк:
1. Ви не можете його підтвердити, навіть для людей з бекграундом.
2. Ви нічого не гарантуєте, бо «We make no warranties, express or implied, regarding».
3. Людина без технічного бекграунда має або найняти адвоката, або не мати справ з цифровими активами.
4. Якби ви вміли критикувати, то ми би з вами зараз не спілкувались.

1. Десь тут вище давав посилання на JS код. Людина з бекграундом все зрозуміє, код елементарний на базі відомих перевірених бібліотек.
2. Ніхто нічого не гарантує)
3. Або використати наш сервіс)

Підписатись на коментарі