Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add best practices for improving security #18

Open
polstianka opened this issue Mar 14, 2024 · 0 comments
Open

Add best practices for improving security #18

polstianka opened this issue Mar 14, 2024 · 0 comments

Comments

@polstianka
Copy link

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:

fun randomSalt(): ByteArray {
    val bytes = ByteArray(256)
    SecureRandom.getInstanceStrong().nextBytes(bytes)
    return bytes
}
    
fun passcodeSecretKey(
    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) ?: throw IllegalStateException("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)

3. Some minor improvements

  1. Using CharArray for PIN to improve memory handling and security. First link from google https://sentry.io/answers/char-vs-string-passwords/

  2. 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.

Good links and examples:

  1. https://developer.android.com/privacy-and-security/security-tips
  2. https://security.stackexchange.com/
  3. https://github.com/OWASP/owasp-mastg
  4. https://labs.withsecure.com/publications/how-secure-is-your-android-keystore-authentication
  5. https://github.com/openwallet-foundation-labs/identity-credential/blob/main/identity-android/src/main/java/com/android/identity/android/securearea/AndroidKeystoreSecureArea.kt
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

No branches or pull requests

1 participant