2

If I am using SHA-512 hash values merely as a means to search fields that have been encrypted elsewhere, is it cryptographically secure enough to hash without salt?

For background, I have been given a non-negotiable requirement to encrypt personal data at the field level. This conflicts with another requirement to be able to search by email and phone number, but I have been told that searching by exact match is a suitable compromise.

To implement this, I remove all personal information fields from my persistence and instead persist a json that I have encrypted with a AWS KMS generated data key. I then also added two columns to my persistence: email hash and phone hash.

Would SHA-512 hashing these values without salt be considered poor security practice? Is it more appropriate to generate a random salt and store that along with the data? If the point is protecting the data at rest, and the salt is sitting in the same table with the hash, how is that more secure?

5
  • 1
    AES_256 hash value - AES is not a hash algorithm, it is an encryption algorithm ("Advanced Encryption Standard", AES for short); big difference - one is designed to be reversible, the other is not :) Commented Jul 29, 2022 at 18:55
  • 1
    Oh! Sorry, I had AES_256 on the brain, I meant to say SHA-512. Corrected.
    – Arlo Guthrie
    Commented Jul 29, 2022 at 18:57
  • 1
    Great no problem; Email and phone number are likely to be unique - you may even be enforcing uniqueness - so the purpose of the salt is not necessary in a use case like that. i.e. probably yes. Usually though the database file is what is encrypted if you need to handle "encrypted at rest" and many popular DB engines have it built in. Commented Jul 29, 2022 at 19:04
  • I think the purpose of the salt if I'm reading documentation correctly, is that it slows the intruder down long enough to change the password because the hash values can't be calculated prior to penetration. In the case of searchable fields that do not change like phone number and email, a salt wouldn't serve any purpose. And yeah, I argued until I was blue in the face for encrypted volumes on my database instead. :D
    – Arlo Guthrie
    Commented Jul 29, 2022 at 19:08
  • 1
    Think of the salt like this: Lots of people are going to end up choosing the same low quality passwords - usually the lowest quality one imaginable (password) followed by pressing whatever keys satisfy the strength requirements. In other words, multiple people end up with the same password and thus the same hash. If you can crack one, you crack them all, simply because SHA-512("password1!") is a constant - thus the apparent speedup. Adding a per-row value, the "salt", guarantees uniqueness of the input value. Commented Jul 29, 2022 at 19:11

2 Answers 2

1

A salt isn't necessary here, but..

Rolling your own encryption storage scheme is often the bad practise in something like this, simply because your application will need the key at some point and therefore your application will need to consider key security otherwise it won't actually add anything to your overall security and may make it substantially worse. For example, rather than the email address identifying someone, the hash does instead - a lot of dangerous information can still be derived from "anonymised" data sets if this isn't carefully managed. So, firstly, an important reminder: Use the built in features of your database engine whenever possible.

What's a salt for?

A salt has a primary purpose of ensuring uniqueness of the input to a hash function. This is why it is incredibly important that a salt is generated using high quality random number generators - that'll make sure they're not predictable. Salts are commonly used on password fields because lots of people are going to end up choosing the same low quality passwords - usually the lowest quality one imaginable (literally the word password) followed by pressing whatever keys satisfy the strength requirements. In other words, multiple people end up with the same password and thus the same hash. If you can crack one, you crack them all, simply because SHA-512("password1!") is a constant. If you prefix the text with some random value, then every input is unique and thus every hash is too.

Why isn't it needed here?

Email addresses and phone numbers are very likely to be unique for your users already, so the salt isn't strictly necessary for its purpose. Given the intent is to search through the set, you can't compare a salted hash with an unsalted one without needing to generate and compare n hashes for n rows in your dataset, and that would likely be extremely slow. Secondly simply hashing a phone number provides little to no security on its own due to the small search space and relative ease of brute force testing all of them. You could of course attempt to do so anyway, but see paragraph #1 again - it is going to be prone to actually making your dataset less secure.

2
  • 1
    There are roughly 3 billion possible US phone numbers. Without a salt, you can do 3 billion hashes, and you've cracked every single entry in the database (in effect, a rainbow table). WITH a salt, you need to do 3 billion hashes to crack EACH entry (or more correctly, half that on average). If you've got a million entries in the database, that's half a million times as much work to crack them all.
    – Doc
    Commented Jul 30, 2022 at 3:31
  • @Doc Whilst yes that's true for the relatively small set of phone numbers, it would not be searchable with a salt - as the other answer notes, you would have to generate a hash to compare against every row. The fundamental usage of a salt in this use case is incorrect. Commented Jul 30, 2022 at 14:33
3

Hashing a phone number is mostly pointless since the search space is relatively small to begin with. There are very few (in crypto terms) options for phone numbers so almost any bad actor would be able to bruteforce your hashes. A unique salt for each user would provide some negligible additional protection, at the cost of a significant slowdown of search operations on large datasets due to the need to hash the search value for each user. Hashing phone numbers is bad design in my opinion, however for a possible solution to the general problem of searching hashed data see bloom filter.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .