Let us say I am creating a program that works offline so password information needs to be stored locally (I know, not optimal, but this is just a personal project of mine). In terms of keeping the password itself secure, I figured I could utilize a KDF such as PBKDF2 or scrypt to derive two keys from the password, one for authentication and another for encryption/decryption to keep the sensitive information inside the program itself safe.

Now let's say I wanted to add an additional feature that the user could limit the attempts at the password such that exceeding these limits would lock a potential attacker out of the program for some period time. My question would be how to keep information such as the number of attempts made at the password secure? For example, the program will log the number of attempts made in a file so that if a potential attacker was to close and reopen the program, the number of attempts already made was saved. What would be a method I could employ to secure this log such that an attacker wouldn't be able to go in and change the logged number of attempts to say 0 and go on for an unlimited number of attempts?

  • Just thinking out loude here: saving it in a format that isn't readable. Write a object to file maybe(binary). – Starlord May 4 '17 at 15:43
  • 1
    Can't be done locally. Why would you want to do it anyway? One thing you can do is use absurd amount of iterations on PBKDF2 or scrypt so that login itself takes some time, say 2 seconds or more depending on what you see as acceptable. – Marko Vodopija May 4 '17 at 15:49
  • Look on how KeePass solved this. They also use KDF with many hash rounds (can be configured by user so a single passwort takes multiple seconds to be calculated) and then it opens an AES container with thah result – BlueWizard May 5 '17 at 5:19
up vote 3 down vote accepted

You're on a hostile device (a user's computer), so have to assume that they can manipulate your code. Therefore, you can't limit in that way: you can ensure that the passwords used are long enough to withstand brute force attempts (e.g. a SHA-256 hash would mean that an attacker would need to try millions of attempts per second in order to be sure of decrypting the data within the lifetime of the universe, assuming perfect implementation of encryption), you can attempt to detect multiple attempts, or you can try and obfuscate the number of tries, but there will always be ways for an attacker to bypass these.

For example, if an attacker ran your software in a VM, they could restore to a snapshot taken before a password attempt when your restriction kicked in.

In order to defeat that, you'd need to control the decryption layer, on a device you control - potentially an internet based service, which returns either decrypted data, or a failure message. You can't just return the correct password, since that would imply that there is some local element where a password can be entered. You can't confirm the password as being correct, for the same reason.

An alternative to an internet based service would be a hardware device which is plugged into the computer of the user, and which acts in the same way: upon a correct password, it returns the encrypted data, else it increments a failure counter and rejects further attempts when this reaches a specific level. This device would need to be tamper-proof - it's no good if you can open it up and read the memory directly. This is essentially the method Apple use with the iPhone, where the separate device is built into the phone, but with very limited interaction with the rest of the system.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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