为什么 golang 包 bcrypt 能够在散列密码后检索盐?
Why is golang package bcrypt able to retrieve the salt after hashing the password?
我无法理解 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
}
根据我的理解,加盐是用来防止攻击者侵入数据库并获得哈希密码列表,为了从哈希中获取原始密码,黑客可以遍历所有有效密码组合并对每个密码组合进行哈希处理他们,如果生成的哈希值之一与黑客数据库中的哈希值匹配,则黑客可以取回密码。在哈希之前添加盐迫使对手重新生成彩虹 table.
关键是将密码与盐一起散列
hash(password + salt)
迫使黑客重新生成彩虹table专门用于盐
但似乎 bcrypt
能够取回盐,所以从技术上讲,如果对手知道系统正在使用 bcrypt 他可以删除盐并获取不是的哈希密码腌制。
换句话说,一旦黑客得到 hashedSecret = hashedSecret[encodedSaltSize:]
他可以使用彩虹攻击取回密码,使盐无用。
我是不是弄错了什么?
he can delete the salt and get the hash password that is not salted.
除了这部分,其他都对。
想象一下,您有一个密码 pass 和两个盐:s1、s2。
散列(s1 + pass) = 123
hash(s2 + pass) = 456
因此您的数据库中将有两条存储记录:
s1$123
s2$456
删除 salt 部分不会让对手到达任何地方,因为他仍然有两个不同的哈希摘要 123 和 456 可以破解.
另一方面,一旦您从用户那里获得明文,这将使您无法重建哈希。
想象一下他们向您发送 通行证。你想要做的是从他们存储在你的数据库中的散列中获取盐子串,例如s2$456,然后和明文拼接,然后比较hash(s2 + pass)和上面的456。如果没有将盐存储在数据库中,您将无法执行此操作,这就是为什么它是必要的。
您可以取回盐,但这并不意味着您获得了未加盐的密码哈希。 “换句话说,一旦黑客获得 hashedSecret = hashedSecret[encodedSaltSize:],他就可以使用彩虹攻击取回密码,使盐变得无用。”具有误导性。攻击者可以获得盐和散列密码,但这不允许“彩虹攻击”。
“彩虹攻击”中的攻击是:生成一个huge彩虹-table一次,前期。该列表是一对 (cleartextpassword,passwordhash) 条目。生成此 table 非常 非常 耗时(如果包含大量密码,可能会变得很大;如果包含所有密码,则可能会变得 庞大!) . “彩虹攻击”中的攻击是:您必须仅生成此彩虹 table 一次 一次 并且可以使用它非常快速地查找数百万密码哈希的明文密码.
由于上面 bcrypt 代码中的每个密码都有其 own salt 你不能使用 one rainbow table:你必须为每种盐创造一条彩虹 table。让“彩虹攻击”失效
我无法理解 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
}
根据我的理解,加盐是用来防止攻击者侵入数据库并获得哈希密码列表,为了从哈希中获取原始密码,黑客可以遍历所有有效密码组合并对每个密码组合进行哈希处理他们,如果生成的哈希值之一与黑客数据库中的哈希值匹配,则黑客可以取回密码。在哈希之前添加盐迫使对手重新生成彩虹 table.
关键是将密码与盐一起散列
hash(password + salt)
迫使黑客重新生成彩虹table专门用于盐
但似乎 bcrypt
能够取回盐,所以从技术上讲,如果对手知道系统正在使用 bcrypt 他可以删除盐并获取不是的哈希密码腌制。
换句话说,一旦黑客得到 hashedSecret = hashedSecret[encodedSaltSize:]
他可以使用彩虹攻击取回密码,使盐无用。
我是不是弄错了什么?
he can delete the salt and get the hash password that is not salted.
除了这部分,其他都对。
想象一下,您有一个密码 pass 和两个盐:s1、s2。
散列(s1 + pass) = 123
hash(s2 + pass) = 456
因此您的数据库中将有两条存储记录:
s1$123
s2$456
删除 salt 部分不会让对手到达任何地方,因为他仍然有两个不同的哈希摘要 123 和 456 可以破解.
另一方面,一旦您从用户那里获得明文,这将使您无法重建哈希。
想象一下他们向您发送 通行证。你想要做的是从他们存储在你的数据库中的散列中获取盐子串,例如s2$456,然后和明文拼接,然后比较hash(s2 + pass)和上面的456。如果没有将盐存储在数据库中,您将无法执行此操作,这就是为什么它是必要的。
您可以取回盐,但这并不意味着您获得了未加盐的密码哈希。 “换句话说,一旦黑客获得 hashedSecret = hashedSecret[encodedSaltSize:],他就可以使用彩虹攻击取回密码,使盐变得无用。”具有误导性。攻击者可以获得盐和散列密码,但这不允许“彩虹攻击”。
“彩虹攻击”中的攻击是:生成一个huge彩虹-table一次,前期。该列表是一对 (cleartextpassword,passwordhash) 条目。生成此 table 非常 非常 耗时(如果包含大量密码,可能会变得很大;如果包含所有密码,则可能会变得 庞大!) . “彩虹攻击”中的攻击是:您必须仅生成此彩虹 table 一次 一次 并且可以使用它非常快速地查找数百万密码哈希的明文密码.
由于上面 bcrypt 代码中的每个密码都有其 own salt 你不能使用 one rainbow table:你必须为每种盐创造一条彩虹 table。让“彩虹攻击”失效