0
$\begingroup$

I am building an Android App where I will be storing some encrypted data in a database. To ensure that the user has entered the right password, I have encrypted my own secret phrase and stored it in the database. Thus, I try to decrypt that using the entered user password to see whether it matches the clear text form.

Given that Android apps can be decompiled, to know my secret phrase, and assume encryption technique be figured out, will it be more useful for a potential hacker to know the clear text? I am using password based key generation (10,000 iterations) to do AES encryption.

$\endgroup$
  • 3
    $\begingroup$ Is there any particular reason you are trying to roll your own password hash instead of using a standard one here? $\endgroup$ – SEJPM Jun 2 '17 at 18:10
  • $\begingroup$ The idea is to ensure the user entered the right password, so that the data can be decrypted properly. It is a usability issues. If they entered a wrong password, then the decryption will not return anything and the user may think that the app is not working. $\endgroup$ – Shahid Thaika Jun 2 '17 at 18:17
  • $\begingroup$ @ShahidThaika This question was asked a lot, look for AEAD or MAC. Please don't roll your own, problems you try to solve were already solved by great cryptographers, you just have to look! $\endgroup$ – axapaxa Jun 2 '17 at 21:43
2
$\begingroup$

OK, so what you are doing right now is the following:

  1. The user enters the password.
  2. It gets run through a PBKDF.
  3. The resulting key is used to verify that a stored string decrypts to "foo bar"
  4. If it does, the derived key is used to decrypt the database.

While this should work and there's no risk with publishing "foo bar" because the data stays inaccessible. It would be a nice idea (from a design point of view) to use a proper verification primitive here. This can be something simple, like verifying that the stored HMAC-value is actually the HMAC of an empty string using the derived key.

While an attacker can swap out said encrypted string in theory, this would gain him nothing with regards to the actual data and only allow him to inconvience the user a bit. Now you could argue that using such a string could inconvience the attacker, but all he would have to do, is to reverse-engineer the application to find the string.

Also note that you must not use the an easier password-based key derivation function for either the password verification or the database decryption because the attacker then gets to chose against which he wants to brute-force.

$\endgroup$
  • $\begingroup$ You are right till #3. I am using a random salt for every row and even modifying the user's password using some other logic. So I need to generate the key again for whichever row I want to decrypt, but they all need the user's password as the base, which resides in his memory. Also, "foo bar" gets stored in the DB in an encrypted form. Only in the code do I check whether the decrypted output equals "foo bar". HMAC value verification seems promising, will need to figure out how in my code. $\endgroup$ – Shahid Thaika Jun 2 '17 at 18:40
  • 1
    $\begingroup$ @ShahidThaika It would be much better from a cryptographic standpoint to derive a key once, purge the password from memory and go ahead and deriving per-row keys from this "master key", you could also store the HMAC-tag in the database entry instead of the encrypted string. $\endgroup$ – SEJPM Jun 2 '17 at 18:50
  • $\begingroup$ I upvoted since what you said makes sense and I may use that in the future, but not only have I already built my app on this principle, a hacker can only get access to my user's DB, if he looses his phone or it gets stolen. Hence, the hacker also needs to decompile my app to know the logic I am using to further manipulate the user's password. Hence, he cannot use a one key decrypts all data solution. $\endgroup$ – Shahid Thaika Jun 2 '17 at 19:00
  • $\begingroup$ @ShahidThaika if the methods used to manipulate the password are the same for all installations of the app, then the attacker only needs to get hands-on with a single copy of the APK to start reverse-engineering process. And if you don't feed the processed password through the PBKDF again, an attacker could try and brute-force a password for any row (because it lacks the 10k iterations?) and then derive the original password again (still assumig a lost phone, but this time the attacker doesn't have to wait on it to RE the app?). $\endgroup$ – SEJPM Jun 2 '17 at 19:04
  • $\begingroup$ Yes you are right. A potential hacker can be ready info regarding user password manipulation logic, hashing method, iteration count, etc. and can work on any row, but they still need to get access to the user's phone and then be able to figure out the password on the extracted database. My concern was whether knowing my own phrase that I decrypt to ensure user has entered the right password would make it easier for the hacker. I do understand that the user has to use a random and long password. It's just that I don't want to make it easier for the hacker because of me. $\endgroup$ – Shahid Thaika Jun 2 '17 at 19:19
1
$\begingroup$

After reading and playing with the idea presented in this post, I have come up with only one area for concern:

(this is to say there might be more, I have not fully analyzed potential attack vectors)

If the adversary has the ability to manipulate values stored in the database, then he may manipulate your secrete value's cipher text (eg. E(k,"foo bar") being changed to some other value). If this is possible for the adversary, then he does not need to know the users password to "authenticate". Instead he may simply encrypt any arbitrary message M with any key K and store the resulting cipher text in place of E(k,"foo bar).

Not all is lost:

Even if the adversary is able to perform chosen cipher text based attacks in order to authenticate, this will not help him decrypt the information in the database, as the cipher text must remain intact in order to retrieve the original message.

As previously stated this is not likely to be the only potential issue, and assuming you have analyzed every attack vector is how we end up with major security breached.

$\endgroup$
  • $\begingroup$ Need to ask these questions before fleshing out a real answer. $\endgroup$ – Kurtis Schlienger Jun 2 '17 at 18:17
  • $\begingroup$ No no, the entire data will be on the client's phone only. User logs in first time and stores data in local SQLite database using a password. I need to ensure he uses the same password the next time and also when he needs the data decrypted. So I use the user entered password to encrypt, for example "foo bar" and stored it in the DB. When the user enters his password, I check whether the decrypted value matches "foo bar" $\endgroup$ – Shahid Thaika Jun 2 '17 at 18:20
  • $\begingroup$ I am not storing the user's password in the database. I am only checking whether the data can be decrypted using the password provided by the user. His password goes through a Hashing algorithm to generate a key that is used to encrypt data. $\endgroup$ – Shahid Thaika Jun 2 '17 at 18:35
  • $\begingroup$ Ah... I see, give me a few minutes to work up an answer. I need to think about ways this "algorithm" can be abused. $\endgroup$ – Kurtis Schlienger Jun 2 '17 at 18:36
  • 1
    $\begingroup$ Do you have any concern for Chosen Cipher-text attacks? $\endgroup$ – Kurtis Schlienger Jun 2 '17 at 18:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.