更改盐无效:为什么散列密码不会因不同的盐而改变?

Changing salt with no effect: Why does the hashed password not change for different salts?

为了保护密码,我们可以在散列时添加盐。不同的盐文本会导致相同密码的不同结果。但我注意到,对于 bcrypt 的不同盐文本,我得到了相同的结果。看这个例子:

library("bcrypt")
my_password <- "password1"

my_salt_1 <- paste0("a$", paste0(letters[1:22], collapse= ""), collapse= "")
my_salt_2 <- paste0("a$", paste0(letters[c(1:21, 21)], collapse= ""), collapse= "")


hashpw(my_password, my_salt_1) == hashpw(my_password, my_salt_2)
TRUE

事实上,很容易创建更多的盐来产生相同的散列密码。例如,我们使用 salt paste0("a$", paste0(letters[c(1:21, 26)], collapse= ""), collapse= "") 得到相同的哈希密码。为什么会这样?这仅仅是因为盐很相似还是这里发生了其他事情?

如果你跳过很多source code (and I'm not 100% sure I did correctly but it seems to match up) it looks like the main issue that the salt bytes are base64 encoded. The two strings you created actually have the exact same base64 decoded value (see Can two different BASE 64 encoded strings result into same string if decoded)。观察

s1 <- "abcdefghijklmnopqrstuv"
s2 <- "abcdefghijklmnopqrstuu"
openssl::base64_decode(s1)
#  [1] 69 b7 1d 79 f8 21 8a 39 25 9a 7a 29 aa bb 2d
openssl::base64_decode(s2)
#  [1] 69 b7 1d 79 f8 21 8a 39 25 9a 7a 29 aa bb 2d

因此您使用的是相同的盐。如果你想获得随机盐,bcrypt::gensalt() 函数是一个更安全的选择

(my_salt_1 <- gensalt(10))
# [1] "a$XBGMfrY0DIVHX3KZVwKmM."
(my_salt_2 <- gensalt(10))
# [1] "a$NM8t5AsKmHJHs0d/hIFlbe"

hashpw(my_password, my_salt_1) == hashpw(my_password, my_salt_2)
# [1] FALSE