I am looking for an algorithm to encrypt secret numbers on a mobile device with these properties:
- Each number has a name associated by the user which is stored in cleartext but may be used to perturb the encryption
- The number has to be encrypted with the password without revealing a hint about whether a given password is right or wrong
- When decrypting with a wrong password, the result has to be a number with equal length (i. e. when the original was 4 digit, the wrong one has to be 4 digit as well)
- When an attacker knows one or a few of the numbers, the easiest way of getting the other numbers should be to brute-force the password until the numbers decrypt to that value.
- It may optionally support other character sets (i. e. 0-9a-f, or 0-9a-zA-Z) - the character set will be stored with the entry and every wrong decryption will reveal only these characters of course
- I assume that an attacker who acquired the mobile device will find a way to dump the encrypted data from it and re-implement the algorithm or any cracking logic, so even when having access to the raw data, it should not reveal information about wrong passwords
As I have SHA-1 available on the device, i was thinking of the following:
- Find the smallest number of bytes where all values of the range can be stored into (for a 3-digit number, use 2 bytes, as 999 does not fit into one byte)
- take the number to encrypt, and test how often you can add
10**digitcount
to it so that it still fits into the range, i.e when encrypting number 555, this is 64, as 65555 > 65536, but when encrypting 222, it is 65, as 65222 < 65536. - Pick a random number from 0 to the number you determined in the last step (linear distribution) and add
number*(10**digitcount)
to the number to encrypt - The result should be a number that is somehow equally distributed over the whole byte range.
- Take SHA-1 of
name+password
, cut off the first (or last) bytes - as many as needed to cover the number from the last step - and XOR them with the number from the last step. - Store the Xor-ed SHA1, the length of the number, and the name.
- Adaptation to other bases than 10 is easy, which can fulfill the optional requirement above.
What do you think? Any ideas to improve it? Any simpler ways to achieve the same? Any obvious flaws I missed?
(And are there any (free as in speech) applications for mobile devices that implement a similar algorithm?)
(Or are there any other stackexchange websites where this question fits better?)
edit: I now accepted the only answer that does not try to tell me the requirements are wrong. Yes, I know the requirements are wrong, but the alternative (store all your PINS in clear text or weakly encrypted on your mobile device) definitely is the larger evil.