Hello, hello, 👋 Let’s review the best practices for password management in an Android application.
First of all, the main rule, never store a password in plain text. I think we all agree on this point. Reading on the subject, I discovered that the String object is not our friend: https://stackoverflow.com/a/53015144 because of the risk to retrieve it by dumping the heap.
Store a hash Link to heading
The best would be not to store the password locally on the device and use passkeys instead but if the need appears we are going to store the SHA-256 hash of the password first. It’s very simple:
val message: ByteArray = ...
val md = MessageDigest.getInstance("SHA-256")
val digest: ByteArray = md.digest(message)
Then, password check consist of string comparison of the stored hash and the generated hash from user input. When exactly identical, the user used a correct password.
Salt use Link to heading
Many argue that the SHA-256 hash alone might be easy to find in pre-compilated hash lists called rainbow tables: https://www.baeldung.com/java-password-hashing#2-implementing-in-java. It’s a security threat!
Countermeasure is simple, it only needs to add a salt. The good news is that the salt can be public and visible so we’ll be able to store it next to the hash.
import java.security.MessageDigest
import java.security.SecureRandom
...
val message: ByteArray = ...
val md = MessageDigest.getInstance("SHA-256")
val salt = ByteArray(16)
SecureRandom().nextBytes(salt)
val digest: ByteArray = md.digest(message + salt)
Checking
val message: ByteArray = ...
val salt: ByteArray = ... // Previously stored salt
val hash: ByteArray = ... // Previously stored hash
val md = MessageDigest.getInstance("SHA-256")
val digest: ByteArray = md.digest(message + salt)
if (String(hash) == String(digest)) println("OK") else println("NOT OK")
Conclusion Link to heading
I hope this introduction to the best practices for password management on the device will be useful for your next assignments. All feedbacks are welcome 😉 A second part is coming in order to store the password and be able to decrypt the password back to the original.