You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
funrandomSalt(): ByteArray {
val bytes =ByteArray(256)
SecureRandom.getInstanceStrong().nextBytes(bytes)
return bytes
}
funpasscodeSecretKey(
passcode:CharArray,
iterationCount:Int = 1000,
keyLength:Int = 256
): SecretKey {
val salt = randomSalt()
val factory =SecretKeyFactory.getInstance("PBKDF2WithHmacSha256")
val spec =PBEKeySpec(passcode, salt, iterationCount, keyLength)
return factory.generateSecret(spec) ?:throwIllegalStateException("failed generate secretKey")
}
After PIN been set, you only need to save the salt and its hash in storage. Not necessarily, but can encrypt them too, like key wrapping. Also you can use other algorithms for this (Argon2 e.t.c.).
2. Encrypt sensitive data based on PIN or biometrics.
Current use of PIN solely as UI element is not a good.
Use this to encrypt API auth token or local database. If the user uses biometrics for authorization, use https://developer.android.com/reference/androidx/biometric/BiometricPrompt.CryptoObject .
It is also good to use second API auth token local encrypted by use PIN or biometric for sensitive actions (request certificates or sensitive information from API)
Customizing KeyGenParameterSpec.Builder for MasterKey in EncryptedSharedPreferences, incorporating stronger encryption policies. For example: setDigests(KeyProperties.DIGEST_SHA512), setRandomizedEncryptionRequired(true) and maybe setIsStrongBoxBacked(true)
Realistic scenario for bypassing current PIN implementation involves gaining physical access to a device, rooting it, and using tools like Frida for skip PIN screen or read encrypted preferences.
This is not critical, but it can be improved and made safer.
I see that the pin code is used exclusively as a feature in UI, but developer still trying to store PIN code in encrypted using https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences.
Honestly, this doesn't make sense if you assume the device won't be rooted (rooted == hacked/vulnerable device), you can just use base preferences https://developer.android.com/reference/android/content/SharedPreferences . Nothing outside can't read this.
Code: https://github.com/diia-open-source/android-diia/blob/main/diia_storage/src/main/java/ua/gov/diia/diia_storage/EncryptedAndroidKeyValueStore.kt#L35
Also, biometric authentication doesn't do anything useful.
Code: https://github.com/diia-open-source/android-diia/blob/main/biometric/src/main/java/ua/gov/diia/biometric/ui/BiometricAuthPrompt.kt#L16
If you assume device on which app is running may be hacked, you should add basic best security practices.
1. Hashing PIN with random salt
Current approach of using EncryptedSharedPreferences for storing PIN, while encrypted, does not fully leverage best practices in secure data stored. It's good practice to hash it with a random salt. First link from google: https://medium.com/@chris_42047/thoughts-on-storing-passwords-securely-in-android-aa3207aede21
For example:
After PIN been set, you only need to save the salt and its hash in storage. Not necessarily, but can encrypt them too, like key wrapping. Also you can use other algorithms for this (Argon2 e.t.c.).
2. Encrypt sensitive data based on PIN or biometrics.
Current use of PIN solely as UI element is not a good.
Use this to encrypt API auth token or local database. If the user uses biometrics for authorization, use https://developer.android.com/reference/androidx/biometric/BiometricPrompt.CryptoObject .
It is also good to use second API auth token local encrypted by use PIN or biometric for sensitive actions (request certificates or sensitive information from API)
3. Some minor improvements
Using CharArray for PIN to improve memory handling and security. First link from google https://sentry.io/answers/char-vs-string-passwords/
Customizing KeyGenParameterSpec.Builder for MasterKey in EncryptedSharedPreferences, incorporating stronger encryption policies. For example:
setDigests(KeyProperties.DIGEST_SHA512)
,setRandomizedEncryptionRequired(true)
and maybesetIsStrongBoxBacked(true)
Realistic scenario for bypassing current PIN implementation involves gaining physical access to a device, rooting it, and using tools like Frida for skip PIN screen or read encrypted preferences.
Good links and examples:
The text was updated successfully, but these errors were encountered: