I have been following this very useful post by Thomas. My use case is slightly different. I am developing a mobile application which requires some sensitive data to be stored on the device in a SQLite File. I am using SQLCipher for encrypting the file. The encryption key is based on a 10 character long(at least one upper-case, one lower-case, one symbol and one number) pass-phrase entered by user at first authentication on that device. SQLCipher internally uses PBKDF2 to generate the encryption key. As per the NIST Publication the entropy for this pass-phrase is around 28 bits.
So according to the formula in post referred above:
v * 2n-1 >> f * p
v: Time required to compute derived key(DK) using one candidate pass-phrase using PBKDF2 function.
n: Entropy of the pass-phrase in number of bits.
2n: Total possible combinations using n bits.
2n-1: Average of 1 and 2n. The average number of candidate pass-phrases to be tried before actual pass-phrase is cracked.
f: Factor representing the computational power available to attacker relative to the system that ‘v’ was calculated on.
p: Patience of the attacker in terms of time.
p comes out to be 7.77 days, using f = 200 (attacker having 200 times the computation power) and using 1 second for one key derivation. As mentioned above, n = 28.
Now coming to my questions:
- What is a realistic estimate for f. I know no one can come up with exact value, but estimates like worst case, average case, etc. would be useful.
- NIST Publication referred above also suggests using dictionary along with composition rules to ensure stronger passwords. I have downloaded password dictionaries here. Now I want to know what does NIST publication mean by transformations of dictionary words? Does it mean that if dictionary contains word "rock" should I disallow all pass-phrase that have rock in them? So rejecting
rock@Ston3e
even though it seems a strong password. - I want to use pepper, so here is how I am planning on using it. Pass-phrase is input to PBKDF2 and
[random-salt(256bit)+pepper(256 bit)]
is the salt for the operation. Several thousand iterations. Then feed the resulting hash to SQLCipher which itself performs 64000 iterations of PBKDF2 with 128 bit salt to reach the encryption key. Is there any problem with the above suggested use of pepper and PBKDF2? - One of my colleagues suggested not storing hashed pass-phrase anywhere on disk. Rather do a SQLite query to fetch some user info from database(this info is needed anyway and hence no overhead). SQLCipher will give an error if pass-phrase entered is wrong since encryption key generated will also be wrong and decrypted SQLite data won't make any sense (not properly formatted as expected by SQLCipher). The advantage I see in this approach is that now hashed pass-phrase is not stored as it is but still its information is distributed in SQLCipher data. So now attacker can not copy hash value from a file and paste it in his/her code and run an offline dictionary attack. He or she can still copy the SQLite file to his/her computer, but now to verify the pass-phrase, an attacker will have to carry out database queries or at least validate the database in some way. My assumption is that while GPUs are fast at calculating hashes, they can't perform these database operations with the same efficiency. Hence the idea is to slow the attacker down by introducing operations that his or her hardware is not optimized for. Is my assumption correct?