Let's say I have a mobile app that can save photos inside password-protected AES-128 encrypted PDF files. For convenience, I want the user to be able to encrypt a file using the previously-used password without having to enter it again, but I also want their data to be safe if the lose their phone or have it stolen. Obviously just saving the password in plain text in the preferences file isn't an option.

In a PDF, the AES encryption key is generated like this:

key = hash(password + file_id + permission_flags)

Where the hash is a combination of RC4 and MD5, and the file_id is a random 128 bit number stored in plaintext in the file. There are a few extra caveats: each object in the file is encrypted with a different key derived from the main one, and there are also separate "user" and "owner" passwords, but let's ignore all that for simplicity's sake, and also assume the permission_flags do not change from file to file.

Encrypting the password for later re-use isn't safe because any method that allows the app decrypt the password and use it to generate the encryption key given a file_id could be used generate it for decryption.

Idea: since the file_ids are just random numbers, we don't have to wait for the files themselves to be created before generating them, we can generate a batch of several thousand file_ids and generate the associated keys given the password and store them as tuples in a file. Then when the user saves a file, we can read out a key and file_id, encrypt the file with the key, writing the file_id to the file, and then delete the tuple. Then if an attacker gets hold of the device they will only have the keys for files that haven't been saved yet, and no way to generate the keys for the files that have. Once the stash runs out, the user simply has to re-enter the password. If the user changes the password, the file is deleted and a new one generated with the new password.

This seems like it might work, but I've never heard of this technique before so I'm reluctant to use it as "rolling your own crypto". It also seems like it could be a problem if the user backs up their device, because then there will be extra copies floating around of all the keys.

What is the best solution for this key-reuse problem, assuming no OS-level system-wide encryption?

  • public-key encryption ​ ​
    – user49075
    Mar 14 '16 at 7:23
  • @RickyDemer How would I allow the user to open and view the files on the same device they encrypted them on? Wouldn't I have to store both public and private keys on the device?
    – samgak
    Mar 14 '16 at 23:36
  • 1
    You would decrypt the private key with a symmetric key derived from the password. ​ ​
    – user49075
    Mar 15 '16 at 6:26
  • @RickyDemer Ok, thanks a lot, I can see how that works in theory. I'm just not sure exactly how or if it's possible to do it that way using the PDF format and have it open in a standard PDF reader app just by entering a password. I had a look through the PDF spec and all the public/private key encryption stuff seemed to be related to digital signing and recipient lists with permission management. I guess I'll have to do more reading, thanks again.
    – samgak
    Mar 15 '16 at 7:12

Your Answer

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

Browse other questions tagged or ask your own question.