Skip to content

Conversation

@jvsena42
Copy link
Member

@jvsena42 jvsena42 commented Jan 11, 2026

Fix #293

Description

This PR prevents sensitive keychain data (mnemonics, passphrases, PINs) from being recovered after app uninstall by:

  1. Encrypting all keychain entries with AES-GCM using a key stored in the app's file system.
  2. Detecting orphaned keychain data on fresh install and wiping it automatically.
  3. Using a Documents marker file to reliably detect app reinstallation.

Breaking Change ⚠️
Users upgrading from master to this branch will have their wallet wiped and will need to restore from their recovery phrase.

This only affects the upgrade path. Normal usage after installation and migration from RN works correctly.

Why Documents Marker?

The encryption key is stored in App Group storage, which persists after uninstall on iOS. The Documents directory is reliably deleted on uninstall, so the marker file serves as the reliable detection mechanism.

Testing Scenarios

  1. Fresh install → Creates wallet normally with encrypted keychain.
  2. Uninstall + reinstall → Detects orphaned data, wipes, shows onboarding.
  3. App wipe (Settings) → Cleans everything including encryption key.
  4. RN migration → Migrates data correctly, then encrypts.
  5. Upgrade from master → Wipes wallet (expected, see Breaking Change above).
reset-and-restore.mp4
unninstall-and-reinstall.mp4
fresh-install.mp4
migrate-from-RN-with-passphrase-and-pin.mp4

…:synonymdev/bitkit-ios into fix/clean-keychain-persistence-uninstall
…edKeychainScenario by creating a documment marker
@jvsena42 jvsena42 requested a review from Copilot January 11, 2026 20:58
@jvsena42 jvsena42 self-assigned this Jan 11, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances keychain security by implementing AES-GCM encryption for sensitive data and adding orphaned keychain detection to prevent data recovery after app uninstall.

Changes:

  • Implements AES-GCM encryption for all keychain entries using a key stored in App Group storage
  • Adds Documents directory marker file for reliable detection of app reinstallation
  • Enhances migration logic to handle RN-to-native transitions and orphaned keychain scenarios

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
Bitkit/Utilities/KeychainCrypto.swift New encryption/decryption utilities with AES-GCM and Documents marker management
Bitkit/Utilities/Keychain.swift Updated to encrypt data before storage and decrypt after retrieval with migration support
Bitkit/Utilities/Errors.swift Added failedToDecrypt error case
Bitkit/Utilities/AppReset.swift Enhanced to delete encryption key and App Group UserDefaults
Bitkit/AppScene.swift Added orphaned keychain detection logic with Documents marker validation
Bitkit/Services/MigrationsService.swift Added RN keychain cleanup after successful migration
Bitkit/Services/VssBackupClient.swift Fixed duplicate setup prevention
Bitkit/Constants/Env.swift Centralized appGroupIdentifier constant
Bitkit/Models/ReceivedTxSheetDetails.swift Updated to use centralized appGroupIdentifier
BitkitTests/KeychainCryptoTests.swift Comprehensive tests for encryption, decryption, and key management
BitkitTests/KeychainTests.swift Updated with encryption integration and migration tests
BitkitTests/KeychainiCloudSyncTests.swift New tests verifying keychain items don't sync to iCloud
Bitkit.xcodeproj/project.pbxproj Added KeychainCrypto.swift to project

@jvsena42
Copy link
Member Author

Draft to implement comments

@jvsena42 jvsena42 marked this pull request as ready for review January 11, 2026 21:25
@jvsena42
Copy link
Member Author

jvsena42 commented Jan 11, 2026

OBS:

  1. A simpler approach is rely only on Documents Marker to identify orphaned keychain data (RN does this), but encrypt the data makes more difficult to restore the keychain data by accident
  2. The encryption key is not stored in documents because it is used by other extensions on app group

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

App is persisting keychain data after uninstall

2 participants