The task may not be solvable in as broad a formulation as in the title, but this is my scenario (which is somewhat similar e.g. to newsletter subscriptions and therefore certainly has already been thought about)
I want to implement a database on a web server where private data about users is stored. The users are not supposed to have a fancy login name, instead they are to be "email validated", i.e., access to a mailbox should be sufficient to authenticate.
Users should be able to create, update, delete only their own data. Central administration should be able to export the data from the webserver to a secured host.
The attack scenario is that the web server together with all data on it (including web page scripts and the database) gets compromised. The requirement is that private data stored there before the compromise remains protected (assuming no further user access is attempted).
Here are my ideas so far: To authenticate I have only the users email
.
- A new enters his
email
into a form, which causeshash(email)
+publicencrypt(email)
+random nonce
+timestamp
to be stored representing the user and the user is sent a mail containing an URL with parametersrandom nonce
andemail
. (As there is only (protected)email
and not (unprotected)username
plus (protected)password
, things like salt cannot be used and I have to resort tohash(email)
, don't I?). - The same happens with an existent user, where only the
hash(email)
will be the same as in any previous attempt.publicencrypt(email)
,random nonce
, andtimestamp
will differ. - Anyone accessing an URL with parameters
email
andnonce
as generated above can perform operations on the corresponding database record after checking: Does there exist a record with matchinghash(email)
and matchingnonce
and not too oldtimestamp
? If yes, the user can proceed. Note that during the web session of this user, the cleartextemail
is available. - The export to the secured central administration host happens by exporting the data encrypted as it is. Decryption happens with the private key matching the public key used to encrypt (the latter is considered public because it resides on the compromisable server).
Adding a new entry is completed at this point, by adding a flag isValid
to the record. Deleting the record is of course easily done. Displaying non-confidential data (e.g., when was the entry created or last modified) is also a trivial task.
My problem is: How to handle additional private data securely?
I might just store it in encrypted form (like the email), but in that case the content cannot even be shown to the authenticated user. He may change it, but cannot decrypt it in a later web session. This is of course sub-obtimal.
My only idea is to encrypt the additional data with a different key: Instead of the public key of an asymmetric key pair use a symmetric key that is reproducibly produced from email
, i.e., store additional data as symmetricencrypt(data,key_generated_from(email))
. As the cleartext email
is available to the user himself during his web session, as well as in the decrypted export on the secured host, data
can be reconstructed.
I see the following problems:
- Given the restricted format of email addresses (e.g., some domains may occur very often), could a key generated from the email as described above be secure enough at all?
- Actually, given the restricted format of email addresses, is the
hash(email)
I used in the basic concept that secures only the email good enough at all? (Is there enough entropy in email addresses, so to speak?) - Is there a better approach?