Hacker News new | ask | show | jobs
by onionisafruit 1400 days ago
The difference between email and password is you can validate a password with a hash, but you can’t send an email to a hashed address. Their db may be encrypted at rest, but a hacker could still compromise a system that has the key in memory.
2 comments

Encrypt the email in column, add hashed email in separated column. Email Sending would then be covered by a separated and "airgapped" system that holds the decryption key, if you need to send mail, you send the encrypted email address plus what you want to send there.

Now an attacker cannot get a hold of email addresses easily.

This is a great idea. You could use public key cryptography too, so that the system adding emails to the db doesn't need the private key.

3rd party mail sending services could support this by generating a keypair on their systems, and only giving you the public half. When you make an API request to send an email, you provide only the encrypted version of the address.

Edit: The hashing is an issue. It's too easy to build a wordlist of possible addresses, to crack the hash. I think this can only work if you drop the hash column, and instead require users to log in using a username.

The hashing is an issue but you need to identify the user somehow when you do things like password resets.

The alternative is to handle everything by a username and password resets also use the username (which would be fine, worst case you get spammed by PW reset mails).

Though of course you can also combat this by making the hash particularly expensive and salt it. Simply take a SHA3-512 of the email address a few thousand times, take the first 12 bits and use that to identify a set of 4096 records. Now the full email is simply an application of Blake2sp, which you calculate in parallel for all 4000 records.

Adjust the 12-bit barrier so that it represents a decent sized chunk of users, lower would mean less load on the login service, higher would mean better anonymity. Instead of SHA3-512 you could also use a bloom filter to find out if a set of records contains the email or not, with the added bonus of being probabilistic.

You could also ditch Blake2sp for a simple round of salted SHA3-512. The fact that you salted it makes dictionary search insanely annoying already.

That's a simple and brilliant idea. I'm running with it.
How would you tell the airgapped system what to send?
I used quotation marks on purpose, it is of course networked, but would be using different credentials to other systems and have a ingest-only API endpoint to issue mails with.
> a hacker could still compromise a system that has the key in memory.

Security is about layers. Simply because a hacker “could” do something, does not mean it’s a bad idea. Getting the encryption key when it’s not stored in the database requires the hacker to now have access not to just the database but to another system as well.

This is an excellent point, but there's nuance to it.

This seems like an acceptable solution for email and a lot of other PII. However, if you were to propose the same thing for passwords, with the same argument, I'd be dead against it -- even beyond the total lack of need for the system to ever have the actual password. I'm not quite sure how to explain this, though.

There’s no reason a company needs to know your password. But they do need to know a way to contact you.
Invariably some developer would just store the key in a column next to the email address so they could process any transaction directly in the query.

But the hackers would have to know what algorithm was used :) That's a layer, right?

> some developer would just store the key in a column next to the email address

I think that depends on where you work. Process. Code reviews before allowing merge/pull requests can help.