You're confusing cryptographic hashes with password hashes. A cryptographic hash takes an input and gives a random looking output. A password hash takes a password and a salt and very slowly gives a random looking output.
What you are worried about here is preimage attacks. You want to ensure that, knowing a hash y
, the attacker cannot find a value x
such that h(x) = y
. 80 bits of complexity is still generally considered "good" (though not "great", and possibly vulnerable to a well funded attacker such as a nation-state). What this means is that you want a hash where the best preimage attack has a complexity of over 80 bits.
Analysis
Let's start with MD5
since it's something of a poster child for outdated crypto. The best known preimage attack on MD5
is 116.9 bits, well above 80. But you want to protect 1 trillion secrets, which lets the attacker do some optimizations.
Let's assume the attacker is able to use a hash table (and many terabytes of RAM) to check if a hash matches any of the 1 trillion in O(1)
. With 1 trillion secrets this reduces the complexity to break a single secret by log2(1012) ≈ 40 bits, which brings MD5
down to around 76 bits. Still not terrible, but worrying if you're facing a nation-state or want to keep these secret for many years.
But you're doing the right thing and using SHA256
. The best preimage attack I could find on SHA256
was for reduced steps, and still had complexity over 250 bits, so you're looking at over 210 bits of complexity there. In this case an attacker will be running into some issues with physics.
SHA256
is not secure for hashing passwords. For hashing >= 16 bytes of cryptographically random data evenMD5
is still reasonably secure.SHA256
would be fine.