Conversation
versionCode might have to be done differently but this works as far as I tested
oSumAtrIX
left a comment
There was a problem hiding this comment.
Some changes need to be made:
- Business logic probably belongs somewhere else than in MainActivity.
- During migration the keystore password is ideally rotated by the user (it shouldnt be hardcoded ideally)
- The old keystore file can be deleted including the old preferences
- Kotlin code can be made more idiomat (e.g. using .apply)
Would moving the whole logic inside MainViewModel::applyLegacySettings be appropriate?
I don't quite understand, should the user be prompted to input a keystore password?
Yeah, for the time being I kept it as is so the data isn't lost while testing. |
Is this really a problem considering the fact that it is only accessible by ReVanced Manager? |
There is no point in doing that as part of a migration process. Also, the keystore is protected by filesystem permissions, so nothing else can access it. |
This makes more sense to me but it would have to be confirmed by someone else
This may fall outside the intended scope. Currently, the keystore passphrase is stored directly within ReVanced Manager; however, a passphrase should always remain user-dependent and must never be stored in plaintext. On Android, sensitive data is expected to be handled through the platform’s secure credential storage. Therefore, the user flow should mandatorily require explicit user authentication when signing an APK, either immediately before signing or earlier, such as at application launch or when patching begins. From a technical perspective, the keystore itself would remain protected by its passphrase, while that passphrase is encrypted using a key derived from the platform keystore. Access to this key is granted only after the user unlocks it via system authentication (for example, fingerprint, PIN, or password). This effectively binds the keystore to a device-protected key that can be accessed solely through user authorization and not by the app itself. |
Yes, saving a passphrase effectively nullifies its purpose. Why have a keystore passphrase thats automatically unlocked when you can also just not have a passphrase. |
Its only protected by policy. We could push an update to dump the key from the app proving its merely a policy. However secrets/passphrases and similar are by principle supposed to involve the user at least once at minimum. A technical example is encrypting the passphrase with the systems key derived from the system keystore. So practically, for example right before the app is signed, a system unlock dialog is shown which unlocks the keystore, cryptographically. The reason this is different from policy is because the fingerprint/pin/passphrase of the system keystore is used in cryptographic context. The key used to encrypt the passphrase cryptographically depends on the users input, not just by policy. But this is out of scope for this PR. Can be introduced later |
app/src/main/java/app/revanced/manager/ui/viewmodel/MainViewModel.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/app/revanced/manager/ui/viewmodel/MainViewModel.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/app/revanced/manager/ui/viewmodel/MainViewModel.kt
Outdated
Show resolved
Hide resolved
# app [1.26.0-dev.23](v1.26.0-dev.22...v1.26.0-dev.23) (2026-02-19) ### Bug Fixes * Flutter migration ([#2946](#2946)) ([31a0f75](31a0f75))
No description provided.