# is it secure to use sha256 to hash 64 cryptographically random byte data with 12 byte salt?

I read from a lot of sources that `sha256` is not secure because it is fast. Most links that I read suggested `bcrypt`. However, I just want to know that if data is 64 cryptographically random byte, will attacker be able to find original string somehow?

Scenerio

`secret string` is 64 cryptographically random byte data

User download `secret string`, we store hashed version of it. He will upload this data to site when he wants to get access to some information. (work process can not be modified, it is stable system we just need to secure it)

System has 1 trillion `secret string` and all of them should be protected by some hash algorithm.

Is it possible that attacker will get even one of the `secret string` if he got access to all hashes?

• `SHA256` is not secure for hashing passwords. For hashing >= 16 bytes of cryptographically random data even `MD5` is still reasonably secure. Feb 8, 2018 at 20:57
• That said, if you have 1 trillion secrets and you don't want an adversary to get even 1, it's maybe possible that a 128 bit output would come close to the possibility of being attacked, but it's still very unlikely. A 256 bit output like `SHA256` would be fine. Feb 8, 2018 at 20:59
• if the attacker is successful (he will earn \$1000), how much it will cost for attacker? @AndrolGenhald Feb 8, 2018 at 21:06
• @AlexRobertson: what kind of trillion do you mean? American (10^12) or British (10^18)? mathcentral.uregina.ca/qq/database/qq.09.02/ryanandaylah1.html Feb 8, 2018 at 21:19
• @SteffenUllrich British Feb 8, 2018 at 21:25

## 2 Answers

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.

• if I use `sha256`, will all of data be secure for many years? what about agaist brute force attack? Feb 8, 2018 at 21:52
• I will accept it as an answer, but I just want to be sure that should I use `sha256` with salt and which `rounds` is recommended in this case? Feb 8, 2018 at 22:20
• @AlexRobertson A salt and multiple rounds are entirely unnecessary when your input has more cryptographically random bytes than the output size of the hash. A single round without a salt is just as good. And it should be good for much longer than the rest of your life. Feb 8, 2018 at 22:24
• Note that OP is talking about a British trillion, which is 10^18. Might want to update your answer accordingly. Feb 9, 2018 at 1:52
• @forest I considered it but decided against considering very few organizations are even capable of storing over 27 exabytes of data. Feb 9, 2018 at 5:35

Specialized password hashing functions like bcrypt are designed to protect secret values that are relatively easy to guess. And that, to put it more technically, means secret values that the following strategy can guess with good practical chances of success:

1. Guess likelier values ahead of comparatively unlikely ones;
2. Try a very high volume of guesses at very large speeds.

Specialized password hashing functions take it for granted that #1 is just a fact of life for passwords, so they try to thwart the attacker on point #2 by slowing them down.

But if you're generating byte strings uniformly at random from a strong, cryptographic generator, then #1 is no longer a problem, so you don't need a specialized password hashing function. The only defense you need is to make the random byte strings long enough. 64 bytes is 512 bits, way more than you need, and in fact if you're passing it through SHA-256 that already pegs your security level at 256 bits, so you gain nothing for using more than 32 bytes. But actually, a 16 byte string (128 bits) should be enough; for example, the cipher that my browser is using to connect to this site uses a 128-bit key, which is an absolutely commonplace security level

• so you mean `sha256` is more than enough, right? Feb 10, 2018 at 18:14