Пусна се Ad Nihilum 0.4.3 — минималистичен сервис за обмен на криптирани съобщения по принципа „прочел — изгорих“, насочен основно към self-hosting.
Сървърът служи само като съхраняваща единица. Шифроването и дешифроването стават изцяло от страната на клиента, в браузера (чрез AES-GCM).
Характеристики
- локално шифроване и дешифроване, сървър никога не вижда ключа;
- поддържане на допълнителен слой на шифроване с парола, за който (1) сървърът не може да узнае, (2) не може да се разбере от предавания линк;
- проектът съдържа около 2200 реда сървърен код на Си и 600 реда клиентски код на JS, което улеснява одита;
- Ad Nihilum зависи само от libmicrohttpd. За генериране на QR кодове се предоставя модифицирана версия на QRCode.js;
- приложена е инструкция за бързо разгръщане на локален сервиз без външен IP;
- Ad Nihilum работи и на Android, приложен е съответен скрипт за компилиране в Termux;
- еднонишков и синхронен сървър.
Промени
Масивен редизайн
- Разделени са страниците за изпращане и получаване на съобщения, съответния клиентски код.
- Дизайнът е променен и коригиран значително, като се взеха предвид пожеланията на лорчаню.
- „Прости“ и локални клиенти:
- клиентските страници могат да се запазят локално и да се използват от file://.
Политики на браузъра
- внедрен е CSP за борба с XSS;
- сървърът изпраща HSTS.
Други промени
- проектът е преименуван от Epha-ots;
- закупен е домейн adnihilum.net;
- TLS се осигурява чрез Let’s Encrypt, което трябва да имате предвид (няма средства);
- оптимизирана работа с файлове;
- преминало е на fat-pointer-и;
- поправени са дребни бъгове;
- авто-jsminify и компилиране на клиентски файлове при компилация чрез CMake.
Преглед на протокола
Генерирайте три случайни стойности: ключ K, вектор на инициализация N и сол S. K — 256 бита, N — 96 бита, S — 128 бита.
Изход ID от K и S чрез HKDF на база SHA-256.
Създайте низ от допълнителни автентифициращи данни aad — това е просто низ от вида: id=ID
Ако потребителят е задал парола:
- изход Pk от паролата и S чрез PBKDF2, SHA-256, 800000 итерации;
- една и съща сол се използва за всичко;
- шифрувайте данните с AES-GCM, използвайки ключ Pk, IV/nonce N и предайте aad.
Добавете двубайтов таг към вече криптираните данни, ако е имало парола, или към оригиналните данни, ако парола не е била зададена.
Първият байт има значение: той показва дали данните са криптирани с парола:
- 0x73 — данните са криптирани с парола;
- 0x13 — данните не са криптирани с парола.
Вторият байт е постоянно значение 0x37.
Отново криптирайте резултата с AES-GCM, като използвате същия iv = N и същия aad. Това дава крайния шифротекст. ct.
Слейте байтовете в стринг: blob = N .. S .. ct
Изпратете blob на сървъра заедно с ID. Сървърът връща blob по този ID и не може да го подмени: клиентът първо ще провери ID с използване на N и K още преди декриптиране, а след това — чрез aad.
Клиентът запазва K. K никога не се изпраща на сървъра. Pk също не се изпраща; всичко, свързано с паролата, се изчиства от паметта.
Клиентът формира линк: origin/#ID/K
Тук ID и K — стрингове в base64url формат.
Когато получателят отвори линка:
- браузърът отхвърля всичко, което започва с #; това се нарича location.hash;
- клиентското приложение се зарежда от сървъра;
- по мое мнение, това е главната дупка: всъщност отново се сблъскваме с факта, че „TLS е пробит“;
- обаче нищо не пречи на клиента да се съхранява офлайн;
- в идеалния случай трябва да има отделен standalone клиент.
Клиентският JavaScript проверява location.hash и ако там има ID и K, той зарежда данни от сървъра.
След това проверява данните, декриптира и, ако е необходимо, иска паролата и декриптира отново.
Лиценз
Проектът се разпространява под GPLv3.
Източник: linux.org.ru
