Why is golang package bcrypt able to retrieve the salt after hashing the password?
Asked Answered
L

2

5

I am having trouble understanding the following code from the golang crypto bcrypt repo

func newFromHash(hashedSecret []byte) (*hashed, error) {
    if len(hashedSecret) < minHashSize {
        return nil, ErrHashTooShort
    }
    p := new(hashed)
    n, err := p.decodeVersion(hashedSecret)
    if err != nil {
        return nil, err
    }
    hashedSecret = hashedSecret[n:]
    n, err = p.decodeCost(hashedSecret)
    if err != nil {
        return nil, err
    }
    hashedSecret = hashedSecret[n:]

    // The "+2" is here because we'll have to append at most 2 '=' to the salt
    // when base64 decoding it in expensiveBlowfishSetup().
    p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
    copy(p.salt, hashedSecret[:encodedSaltSize])

    hashedSecret = hashedSecret[encodedSaltSize:]
    p.hash = make([]byte, len(hashedSecret))
    copy(p.hash, hashedSecret)

    return p, nil
}

From my understanding salting is used to prevent adversaries that have hack into the database and obtain a list of hashed passwords, to obtain the original password from the hash, hackers can go through all valid password combinations and hash each one of them, if one of the generated hash match with the hash in the hack DB the hacker can get the password back. Adding a salt before hash force the adversary to regenerate the rainbow table.

The key is to hash the password along with the salt

hash(password + salt)

forcing the hacker to regenerate a rainbow table specifically for the salt

But it seems like bcrypt is able to get the salt back, so technically if an adversary knows a system is using bcrypt he can delete the salt and get the hash password that is not salted.

In another word once the hacker get hashedSecret = hashedSecret[encodedSaltSize:] he can use rainbow attack to get the password back making the salt useless.

Am I getting something wrong?

Linn answered 11/11, 2020 at 6:10 Comment(0)
G
10

he can delete the salt and get the hash password that is not salted.

Everything except this part is right.

Imagine, you have a password pass and two salts: s1, s2.

  • hash(s1 + pass) = 123

  • hash(s2 + pass) = 456

So you would have two stored records in your DB:

  • s1$123

  • s2$456

Deleting the salt part won't get the adversary anywhere as he would still have two different hash digests 123 and 456 to crack.

On the other hand, it would render yourself unable to reconstruct your hash once you get cleartext from your user.

Imagine them sending you pass. What you want to do is to get the salt substring from their hash stored in your DB, e.g. s2$456, then concatenate it with the cleartext and then compare hash(s2 + pass) with 456 above. Without having your salt stored in the database you can't do this, that's why it is necessary.

Gypsy answered 11/11, 2020 at 6:34 Comment(0)
U
5

You can get back the salt but that doesn't mean you get the unsalted password hash. "In another word once the hacker get hashedSecret = hashedSecret[encodedSaltSize:] he can use rainbow attack to get the password back making the salt useless." is misleading. The attacker can get the salt and the hashed password but this doesn't allow a "rainbow attack".

The attack in "rainbow attack" is: Generate a huge rainbow-table once, upfront. The list is a pair of (cleartextpassword,passwordhash) entries. Generating this table is very timeconsuming (and might become large if you include lots of passwords and huge if you include all passwords!). The attack in a "rainbow attack" is: You have to generate this rainbow table only once and can use it to look up cleartext passwords for millions of password-hashes very fast.

As each password in the bcrypt code above gets its own salt you cannot use one rainbow table: You would have to create one rainbow table for each salt. Rendering the "rainbow attack" useless.

Urogenital answered 11/11, 2020 at 6:39 Comment(1)
More specifically, generating a rainbow table that covers a set of passwords is more work than brute forcing that same set of passwords.Thorstein

© 2022 - 2024 — McMap. All rights reserved.