Initial commit: QSafe Android 1.1.0 and Windows 1.0.4

This commit is contained in:
Курнат Андрей
2026-11-01 15:28:12 +03:00
commit 9845944bb8
91 changed files with 6496 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
# QSafe для Windows
Нативный WPF-клиент на .NET 10 с тёмным интерфейсом, поиском, избранным, восемью шаблонами карточек, корзиной, редактором произвольных полей, генератором паролей и синхронизацией с существующим Pi. Исходники в `QSafe.Core` и `QSafe.Desktop`, проверки в `QSafe.Tests`.
Готовая переносимая версия: `../artifacts/QSafe-Windows-1.0.4/QSafe.exe`. Отдельная установка .NET не нужна. ZIP содержит EXE и краткую инструкцию. Сборка x64 проверена на текущей Windows; других архитектур в поставке нет.
Генератор в редакторе карточки показывает пароль открыто до применения. Доступны сложный пароль (16–64 символа, специальные символы по выбору), цифровой код (4–64 цифры) и запоминающийся пароль (2–12 случайных английских слов с отдельными переключателями цифр и специальных знаков; цифры и знаки случайно размещаются перед словами, между ними или в конце, сохраняя слова целыми). Длина меняется ползунком и отдельно запоминается для каждого режима до закрытия окна. Для слов показывается также итоговое число символов. **Другой вариант** обновляет результат, **Использовать пароль** подставляет его в поле, **Отмена** сохраняет старое значение. Самостоятельный генератор из бокового меню использует те же настройки и явную кнопку копирования с прежней очисткой буфера. Список из 256 слов общий с Android; все режимы используют криптографическую случайность и работают без сети.
## Совместимость и данные
Формат `QSAFE01!` полностью повторяет Android: big-endian число итераций, 16 байт соли, 12 байт nonce, 40-байтный аутентифицируемый заголовок, AES-256-GCM с 16-байтным тегом. PBKDF2-HMAC-SHA256 использует 600 000 итераций. Межплатформенная проверка запускает фактический `app/src/main/java/ru/kusoft/qsafe/VaultCrypto.java` и обменивается файлами в обе стороны с Unicode-паролем.
Дополнительные JSON-поля сохраняются на уровне базы, карточек и полей. Вложения и XML-источник импорта остаются внутри зашифрованной базы. Секреты и заметки не участвуют в поиске. Импорт XML запрещает DTD и внешние сущности; до записи пользователь получает счётчики импорта и подтверждает перенос.
Хранилище находится в `%LOCALAPPDATA%\Kusoft\QSafe`; атомарная запись использует временный файл с `Flush(true)` и замену файла. Перед записью создаётся зашифрованная резервная копия, хранятся последние 10. Доступ к базе одновременно ограничен одним процессом для данного каталога. `connection.enc` защищён Windows DPAPI для текущего пользователя. Пароль и мастер-ключ не записываются на диск. Управляемая память не позволяет гарантировать стирание всех копий строк.
База доступна только по буквальному частному IPv4 непосредственно в подсети физического домашнего Wi-Fi. Точное имя SSID проверяется через Windows WLAN API перед каждым GET/PUT и повторно при создании сокета. Сокет привязывается к IP и индексу Wi-Fi-интерфейса (IP_UNICAST_IF); прокси, DNS и перенаправления исключены. Вне дома приложение работает с локальными данными. Ручная синхронизация и восстановление не обходят ограничение.
HTTPS проверяет имя/IP, срок действия и точный SHA-256 локального сертификата Pi из личного файла подключения. Загрузки сертификатов и онлайн-проверки отзыва отключены для этого закреплённого локального сертификата. До замены локальной базы проверяются SHA-256, GCM-тег, JSON и идентификатор хранилища. PUT требует `If-Match` или `If-None-Match`; при HTTP 412 выполняется до трёх попыток с новым GET. Трёхстороннее объединение сохраняет конкурентные правки и конфликты удаления.
Pi: `https://192.168.0.185:18443/qsafe/`, домашний SSID `gen`. Локальный файл `.private/connection-lan.qsafe` содержит также ключ доступа и не входит в поставку. Старые файлы с внешним адресом отвергаются до сетевых запросов. Одноразовая настройка Windows без открытия базы: `QSafe.exe --connection <личный-файл> --configure-only`. Для Android импортируйте обновлённый личный файл в настройках подключения. Публичный путь базы на Аргусе закрыт; обновления APK через Аргус сохранены.
## Сборка
Нужны Windows и .NET SDK 10. Java 17 необязательна для сборки, нужна для межплатформенной проверки.
```powershell
.\windows\build.ps1
```
Скрипт запускает проверки, Java interoperability при доступном JDK, публикует self-contained EXE, выполняет проверочный запуск с автоматическим выходом и формирует ZIP и SHA-256. Для быстрой пересборки без тестов предусмотрен `-SkipTests`.
```powershell
dotnet run --project windows/QSafe.Tests -c Release -- artifacts/windows-qa
dotnet run --project windows/QSafe.Desktop -- --demo
```
Тесты создают только синтетические данные в `%TEMP%\QSafe-Tests` и `%TEMP%\QSafe-Demo`. WPF-рендеры создаются внутри тестового процесса без ввода в Windows и без открытия рабочего хранилища. `--smoke-test` запускает отдельную временную демонстрацию и автоматически закрывает приложение через 2 секунды.
## Ограничения первой версии
Автосинхронизация работает только при открытом разблокированном приложении раз в минуту и только внутри домашнего Wi-Fi. При неизвестном SSID, отсутствии разрешения Windows на его чтение или другой сети приложение остаётся автономным. Вложения сохраняются, но не просматриваются. Нет Windows Hello, TOTP, смены мастер-пароля, интеграции с браузерами и автообновления Windows. Снимки обычных окон исключаются из поддерживаемого системного захвата через `SetWindowDisplayAffinity`; это не защита от всех способов захвата. Очистка буфера работает, пока процесс запущен, и не затирает новое содержимое другого приложения. EXE не подписан. Независимого аудита не было. На рабочем Pi проверено только чтение зашифрованной базы по локальному TLS; мастер-пароль и открытые данные пользователя не использовались.
API: [AES-GCM .NET](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.aesgcm.encrypt), [Windows DPAPI](https://learn.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata).