views:

146

answers:

3

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.

A: 

You could simplify this, I think, if you're not overly concerned about an attacker knowing how many digits are in the number. (Which presumably you are not, since you specify that a wrong password should still return the correct number of digits.)

Just store the number as an ASCII string, XORed with the first number-of-digits bytes from the SHA-1 hash you've computed.

Then when decoding, brute-force any "digit" that decodes outside the range back into a valid digit. (E.g., if the valid digits are '0'-'9' just subtract '0', modulus 10, and add '0' back.)

Kaelin Colclasure
but doesn't the fact that you have to brute-force the digit tell you that the password was not the one used to originally encrypt it?
mihi
A: 

The glaring flaw I see in all of this is that you are only encrypting the password. Time and time again it has been noted that only encrypting the "important" information is a sure fire way to get into trouble. Also I don't think you are going to be able to get brute force to be the technique here you are more likely to lose to a birthday attack. Which as I recall is different than brute force, feel free to correct me if I am wrong. Additionally the clue that it is the wrong password will be that you are not granted access.

Woot4Moo
the numbers I am thinking about are only useful if you also are in possession of a piece of plastic, and the machine will take the piece of plastic if you enter the wrong number three times... If the thief has no clue about the password the PIN is encrypted with, he should not be able to reduce the number of trials from say 1000 to 3, and I don't see how he could in this scenario. Maybe I am just a bad cryptographer, though...
mihi
The thief/hacker always knows the algorithm. Also the thief is not trying to match the string he is trying to match the hash of the string
Woot4Moo
I think you are misunderstanding my question. I don't want to store passwords so that others can authenticate themselves, but store passwords I can use to authenticate to third parties (like banks). And it does not make the bank's system more insecure when the users store their passwords encrypted on a device instead of writing them on a piece of paper in their wallet :)
mihi
I don't believe its a misunderstanding on my part, your application now becomes the Achilles heel of security. If you are storing sensitive information you MUST encrypt everything on that device to be fully secure.
Woot4Moo
A: 

Just to provide you with an idea for a simpler approach: Use the good old DLP in finite cyclic groups.

Additively written: cipher = plain + key mod 10^number-of-digits then clearly: cipher - key mod 10^number-of-digits = plain again, and it's always going to be in the target interval by design.

hroptatyr
Please don't invent your own crypto system, unless you want it broken quickly by people who know what they're doing.
Nick Johnson
@Nick: Define 'your own crypto system' :) My suggestion is merely a one-time-pad, I've written nothing but the actual definition of the encrypt and decrypt 'routines' of OTP.
hroptatyr
It's not a one time pad unless you only use the key once, in which case you have the significant problem of how to distribute keys. See why inventing one's own crypto systems is a bad idea?
Nick Johnson
It is an OTP in the sense that every key bit modifies one bit of the plain text, of course you'd use a different key for every `record`, the key distribution scheme could be `hash^N(password)` where `N` is the record number.
hroptatyr
And just to provide the attack also: Suppose you obtained the key for record `N` you can now read every record `k >= N`. If you got all but one bit of the `N`-th key, you get to read two versions of record `N`, 4 versions of record `N+1`, 8 versions of `N+2`, etc.
hroptatyr
It's _not_ a One Time Pad unless the key is entirely random - not pseudo-random, not generated by something else, and used only _once_.
Nick Johnson
No, *if* the key is drawn from a uniform distribution and used only once *then* you can prove that the cipher is unbreakable. That wasn't the OP's objective though.
hroptatyr