Этап 0 п.3 (доп): биометрическая привязка app password поверх шифрования
Auth-bound RSA-пара `f7_auth_master_bio` в AndroidKeystore (setUserAuthenticationRequired + setInvalidatedByBiometricEnrollment, per-use CryptoObject, префикс v2b:): ПУБЛИЧНЫЙ ключ шифрует без авторизации (в т.ч. в фоне — миграция/сохранение после входа), ПРИВАТНЫЙ расшифровывает ТОЛЬКО через BiometricPrompt+CryptoObject. Симметричный AES не подошёл бы: там auth требуется и на шифрование. Разрешение конфликта с фоновыми push/звонками: пароль расшифровывается ОДИН раз при разблокировке (AppLockGate) и живёт в памяти процесса (AppPasswordHolder, не на диске). AuthStore.load() в фоне возвращает null, пока «холодно» → существующие `?: return` в push/звонках деградируют сами; экраны Accept (CallIncomingActivity, TalkPushBridge) открывают приложение для разблокировки вместо тихого отказа. AppScaffold через loadMetadata() показывает экран блокировки, а не логин, и перечитывает сессию после разблокировки. ВЫКЛ по умолчанию (AppLockStore.isPasswordBindingEnabled, только при биометрии-без-PIN — единственный путь разблокировки прогревает holder). UI-тумблер и включение по умолчанию — ПОСЛЕ подтверждения владельцем поведения «после ребута до первой разблокировки звонки/push не работают» (как в Signal). v0.5.115 (123). Проверено сборкой assembleRelease на инфре B: APK 54.6 МБ, подпись v2+v3 OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+10
-1
@@ -62,10 +62,19 @@ legacy WebView-оболочки `android-webview`.
|
||||
## Секреты (где, НЕ значения)
|
||||
- В git секретов нет. Учётные данные пользователя — только на устройстве
|
||||
(session storage `core/auth`).
|
||||
- App password шифруется в покое ключом AndroidKeystore AES-256-GCM (`KeystoreCrypto`,
|
||||
ключ `f7_auth_master`, префикс `v1:`). Опционально — **биометрическая привязка**
|
||||
(`AppLockStore.isPasswordBindingEnabled`, ВЫКЛ по умолчанию): пароль шифруется
|
||||
auth-bound RSA-парой `f7_auth_master_bio` (`setUserAuthenticationRequired`, префикс
|
||||
`v2b:`), расшифровывается ТОЛЬКО через BiometricPrompt+CryptoObject один раз при
|
||||
разблокировке и живёт в памяти процесса (`AppPasswordHolder`, не на диске). Фоновые
|
||||
сценарии (push/входящие Talk-звонки) до первой разблокировки после ребута деградируют
|
||||
корректно («Разблокируйте приложение…»). Включение по умолчанию/UI-тумблер — ПОСЛЕ
|
||||
подтверждения владельцем допустимости этого поведения (как в Signal).
|
||||
- `google-services.json` (Firebase) — вне git; путь сборки документируется в
|
||||
PROJECT-STATUS.md.
|
||||
- Release-keystore для подписи — вне git (пока не настроен, сборки debug).
|
||||
|
||||
## Версия / changelog
|
||||
- Текущее: v0.5.113 (code 121) — модуль «Задачи». История — CHANGELOG.md
|
||||
- Текущее: v0.5.115 (code 123) — биопривязка app password (Этап 0 п.3 доп). История — CHANGELOG.md
|
||||
и git-история `app/build.gradle`.
|
||||
|
||||
Reference in New Issue
Block a user