Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

As part of an application I am developing, I am required to store user email adresses on a cloud DB. The email address is not required to be in plain text for the normal operation of the application.

So, to provide security, the email address is being encrypted and then stored in the database. The email address in the encrypted form will be the primary means of identifying users (it is the primary key).

Given these facts, which of the following encryption methods makes sense if the database server is vulnerable to attacks.

Method 1:

Encrypted-Email-Address = Asymmetric Cipher(Pub-Key2, 
               Asymmetric Cipher(Pub-Key1, Plain-text-Email-address))

No random padding will be used to allow for deterministic mapping between plain and cipher email addresses, hence encryption twice

OR

Method 2:

Encrypted-Email-Address = Symmetric Cipher(Key, Plain-text-Email-address)

Note that because decryption is not required for the normal operation, the private Keys in method 1 will be stored offline in the physical world. The encryption will need to be deterministic though because the email address is the primary key.

I did go through http://stackoverflow.com/questions/6980044/using-asymmetric-encryption-to-secure-passwords. But there the OP is looking to store a non primary key field, so I am unable to use it.

Are you aware of any better methodologies which solve this use case?

share|improve this question
5  
You should not be using the email address, encrypted or otherwise as a primary key. Email addresses (and other "natural" keys) can change. Use surrogate keys. This will completely remove the requirement that email addresses be encrypted deterministically, which is fundamentally incompatible with many common notions of cryptographic security. –  Stephen Touset Sep 30 '13 at 20:53
    
This backend supports a mobile application in the front, so there are usability issues. Identifying the user becomes a problem if he/she logs in using a different device because I can't ask the user to remember his/her surrogate key (or a username that they may have chosen). Users remember their email addresses. I don't even need to ask for the email address and instead source it from the mobile platform without them having to type anything for sign-up or log-in. –  dvlpr Oct 1 '13 at 4:34
    
I think you're both mixing up index and primary key. You can still index a column containing the hashed value of the email address while using a surrogate key as primary. It even makes sense from a performance point of view if the primary key is clustered. What @dvlpr means is that he wants to use the email address as the main identifier for the user. –  Stephane Oct 1 '13 at 8:47
    
I don't understand why you couldn't simply use a keyed hash (HMAC) of the email (after normalizing the case) as lookup key for the account. Assuming that is not the only element that will allow the user to authenticate (i.e. you have a password in addition to the email address) that seems to fit your requirement. –  Stephane Oct 1 '13 at 8:50
    
Authentication is through OAuth, so I am not storing the passwords. About HMAC and symmetric ciphers, I am paranoid about storing the key on the same server as the data when no active decryption is required as part of normal operations. Seems like that is something that could be avoided. –  dvlpr Oct 1 '13 at 12:46

2 Answers 2

up vote 0 down vote accepted

As far as I can tell, you're using the email address for 2 separate purposes, so why not store it twice?

In one column, you could store a hashed version, much like you would store a password. That's deterministic, so you can use it to look up a user by their email address.

Though, as others have mentioned, it's not a good idea to use it as a primary key. Use a surrogate key (e.g. an auto-increment) and create a unique index on the email column.

Then in a second column, you'd have an asymmetrically-encrypted version that you can decrypt with an offline private key if you ever need to. This one would not need to be deterministic, so you can use standard asymmetric encryption.

share|improve this answer
    
Thanks for your response. But I think the problem is unsolvable. Hashing a small/predictable string like email address without a per-email salt is still vulnerable to enumeration attacks as @Tom Leek mentioned :( The real problem is that we can only pick two out of these three: 1. Asymmetric, 2. Deterministic and 3. Strong. I would have loved to pick all three, but looks like its just not possible at this time. I think I will probably use a symmetric cipher and try to protect the key as much as I can. I only wonder how facebook/twitter do it. They too use emails to identify users. –  dvlpr Oct 4 '13 at 6:58
    
@dvlpr Good point. To be honest, I think a lot of sites don't bother to protect the email - just checked a couple of test sites' DBs (Drupal and MediaWiki) and they've got plaintext email addresses in them... –  just me Oct 4 '13 at 9:32

Email addresses are subject to enumeration. There are not so many email addresses. Any deterministic scheme which uses no secret (i.e. no key that a possible attacker knows of) will do nothing against that. I don't know what you suppose that the "double asymmetric encryption" with two public keys achieves; but I know that it does not fix that core problem. Public keys are public.

Symmetric encryption, with a key that the attacker does not have, can be deterministic and yet safe (if done properly) but this hardly applies to your situation, since while you don't need decryption, you do need to encrypt a lot, because the user's email address is what the user types in.

An additional problem with email addresses is that they are not always reproducible: users may employ different casings (case is not significant in the domain part, after the '@', but it may be significant in the local part), use variants (many people have 'login@domain.com' and 'firstname.lastname@domain.com' as valid addresses) and include "comments" (as in 'bob+emailForSpammers@domain.com') with a site-specific notion of what constitutes a "comment". As @Stephen suggests, it is better to simply allocate an ID to each user and use that ID as primary key.

share|improve this answer
    
Thanks for your response. The reason I am trying to encrypt twice is because without random padding I know that asymmetric cipher is weak. Maybe the second asym() cipher will strengthen it (because the output of first is 2048 bits)? And when you say public keys are public do you mean that public keys come out of a small set which can be guessed by attackers? Because the public keys on the server are going to be afforded the same level of protection that a symmetric key will get. They will not be released to the public. –  dvlpr Oct 1 '13 at 5:20
    
Those enumeration attacks are practical. I recovered 28% of stackexchange emails and reversity recovered 45% from some forums thanks to gravatar publishing a hash of the email address. They apply to any deterministic function, but can be slowed down using a slow function, like scrypt, bcrypt or PBKDF2. –  CodesInChaos Oct 1 '13 at 7:55
    
Public keys are not meant to be hidden, and in many cases can be recomputed from observed messages. And whoever encrypts must know them, so they cannot be really secret. As for accumulating layers in hope of some "strengthening", it is like throwing a pinch of salt over your shoulder so as to bring good luck: what you suggest amounts to: "yeah, one pinch of salt does not work, but maybe throwing a whole bucket will do the trick ?" –  Tom Leek Oct 1 '13 at 10:56
    
Yup, I know that double encryption is a shot in the dark :( What it looks like is there is no established method for this scenario. Because this use case is real and does add value in terms of security. –  dvlpr Oct 1 '13 at 12:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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