I want to create an Android app where users from an office (typical use) can upload scanned documents to the app backend service for later use.

e.g. A lawyer want to upload a sentence sensitiveDocument.png.

The guaranteed privacy for the user is a important sale point for the product. From the previous example, the lawyer wants that he is the only person who can read the document, neither myself as a S3 administrator (I plan to use Amazon S3 for the storage), and not to mention other users.

Also, I want to assure to my users that I can't read their files.


A user key controlled by the user: the user symmetrically encrypts the file with its key, uploads the file encrypted and when he want to read the file, he retrieves the encrypted file and decrypts it on the Android app.


  • The user has to remember another bit of information besides the password.
  • Alternative to the previous one, the app can automatically generate and store the key but...
  • Either way the user can lose the key, for the first case e.g. if he forgot the key, and in the app side e.g. if the key is accidentally deleted or the phone is stolen, etc.

Is there a way to do this properly?

  • I don't believe that guaranteed privacy is possible on Android (or iPhone) using stock and firmware. Users don't have root, and can't prevent leaks. – mirimir Jan 16 '14 at 2:51
  • The guaranteed privacy ... Android app ... Amazon S3 ... did not read much news lately? – that guy from over there Jan 16 '14 at 6:25
  • The NSA and others news, I know @thatguyfromoverthere – sanrodari Jan 16 '14 at 14:55

If the user can read his document, but you cannot, then the user must "know" (i.e. remember or store) some value that you do not. A secret "value" which is used to unlock access to some documents: cryptographers call such values "keys".

A password is a key that the user can remember, i.e. he can store it in his brain. This has shortcomings, foremost of which being that realistic passwords are weak against brute force. Appropriate password hashing is used to try to cope with this weakness. In any case, users can forget passwords.

From a cryptographic point of view, a "reasonable" way of doing things is the following:

  • Each user has two "passwords": his normal one (P) and a "recovery password" (R) which is not really a password, in that it is a big sequence of random letters, and the user will not try to remember it.
  • The user writes down the recovery password on some piece of paper that he stores in a safe place (e.g. in a bank). The recovery password is there to recover the data when the user forgets his password.
  • Each file is encrypted with a symmetric key K, called the "master key" (each user has his own "master key").
  • The storage system, where the documents are, also contains the encryption of K by P, and the encryption of K by R. When encrypting "by the password P", I mean that there is a user-specific random salt used in a good password hashing function to convert P into a symmetric key KP, and that symmetric key is used to encrypt K. Similarly with R.

When the user wants to read his documents, he enters P, from which KP is derived (using the stored salt); this allows recovering K, and thus decrypting the documents.

When the user changes his password into P', it suffices to recover K (as above), generate a new salt, then compute KP', encrypt K with that, and store the result (along with the new salt) on the server.

When the user forgets his password, he goes to his bank, retrieves his recovery password R, and uses it to recover K and then choose a new password.

With the above, the storage server sysadmin may obtain enough information to "try passwords" (that's called an "offline dictionary attack"). This is unavoidable, and that's why we use a good password hashing function with salts and many iterations.

As @scuzzy-delta indicates, a critical point is that the customer is not a developer, so he will necessarily have to trust some software, at some point, not to play nasty tricks on him. This covers your app, but also the operating system; and, more generally, it will be up to the customer to ensure that his PC is not malware-ridden. Under these conditions, you cannot guarantee that the customer's documents will not be pillaged; but you can ensure that you will not be blamed for it, if you get your code audited (remember that your customers are lawyers: they may be fierce). Audit is very expensive, and increasingly more so if the code is bigger, so you want to keep you app as small as possible.

Cryptography is known to be tricky to implement, so you are widely encouraged to stick to existing standard formats and, if possible, standard libraries. The OpenPGP format would be a good place to start. Ideally, you would find a good format already implemented by both Android and iOS (code which is already in the phone needs not be audited, at least not for the audit which covers your own skin).

|improve this answer|||||

One further step is to use a key derivation function to derive a key from the user's password. You can then encrypt the data key used for encrypting each file with the user's derived key and you can store the encrypted form of the data key on your server with the file. Without the user's password the key can't be used, but it also lets the user access it from multiple devices without having to deal with key management.

|improve this answer|||||

@AJ Henderson is correct - use a key derivation function instead of making the user create/remember/enter the actual key.

Beyond that, you mentioned that you want to reassure the user that you can't read their files - meaning you need to provide some proof that you are sincere. The best proofs are expensive to fake. So you could consider the following:

  • Open-source the code for inspection
  • Offer a "security bug bounty" (for extra points, have it held in escrow by a neutral 3rd party)
  • As an alternative or an addition to open-sourcing, invite a respected third party to perform a source code audit (the process is currently underway for Truecrypt and is very interesting to follow).
  • Promise refunds in the event of a security breach
|improve this answer|||||

Your Answer

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

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