There are ways to do these things though so the spirit of your comment is correct.
Do you have a link to anything that explains why, and what the ways are to do these things?
I’d assume encryption wouldn’t help much since wouldn’t the key most likely be available if the database was compromised?
I would have thought hashing would work if it’s made more expensive such as by choosing an expensive hash function and increasing the number of rounds.
Edit: Would first encrypting the value with the salt and then hashing the encrypted value and salt add more entropy and make hash collisions less revealing?
The best thing to do tends to depend on how you need to use the data, exactly.
With hashing alone there's just no reasonable cost function that will provide (say) 1 year of security in the event of database exfil, but also not DoS your service computing it :/ The problem is being offline-attackable.
Encryption is one possible answer and I think most HNers understand the tradeoffs. Generally the less transparent it is, the more effective it is. Volume encryption or transparent database encryption are good to turn on, but don't protect you much. Keys available at application level only (let's say some fields are KMS'd) are better and will be of use under common failure scenarios (SQLi / DB exfil). You still have to get key management and application security right though and it turns out those are hard to do at scale. Your encrypted fields will also not be efficiently searchable unless you are using deterministic encryption.
The tokenize pattern replaces sensitive data with a random value which is mastered in a centralised, controlled service. This really only makes sense if you can set things up so that almost all operations can be performed using the token.If you allow too many things to do token -> value lookups then it's pointless. Also all your eggs are now in basket so you have to watch that basket. Operations look like:
- Exchange sensitive value for token
- Compare tokens for equality (optional, but usually handy)
- "Domain operations on token". For credit card, "bill the user", for phone numbers your domain operations might be "send SMS" or "robocall".
- Exchange token for value (controls go here; limit access to customer service staff only, auditing, rate limits etc. The value should ideally only come out if a human has to look at it, and you should be able to definitely say who looked at what).
This is a general technique, mostly used for credit cards. There's a whole industry around it. https://en.wikipedia.org/wiki/Tokenization_(data_security)
Anchored hashing uses a secret value in your "hash" operation. Keeping this value actually secret is hard, so an "industrial strength" implementation will use an HSM or other hardware to do the operation. This means any brute-forcing has to happen inside your network where you can see it. You ideally want a bit more entropy than with tokenization to make this work, but with appropriate rate-limits against attack from inside your infrastructure, it has legs. It's hashing, so works well for "have I seen this sensitive data before". The main advantage of this pattern is that it doesn't have to keep state.
A decent write up of "anchoring" is here: https://diogomonica.com/2017/10/08/crypto-anchors-exfiltrati...
So it sounds like all of these techniques are to force sensitive data access to a single well secured point 1) with the hope that these actions will be eventually noticed and 2) to enforce rate limits on actions to slow progress and increase exfil duration to support (1). (2) can only be made so slow since, as you mentioned, the service needs reasonably quick access.
On a related note some HSMs can enforce rate limiting in hardware so even if the machine enforcing this access is compromised the rate limits still cannot be bypassed.
If you use a secret you have the same problem as before the legit system need to have access to the secret but an attacker should never get it. So if an attacker gets hashes and the secret(s) he has everything.