更改盐没有效果:为啥散列密码不会因不同的盐而改变?

Posted

技术标签:

【中文标题】更改盐没有效果:为啥散列密码不会因不同的盐而改变?【英文标题】:Changing salt with no effect: Why does the hashed password not change for different salts?更改盐没有效果:为什么散列密码不会因不同的盐而改变? 【发布时间】:2021-11-30 12:36:12 【问题描述】:

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

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

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


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

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

【问题讨论】:

【参考方案1】:

如果您跳过很多 source code(我不能 100% 确定我做对了,但它似乎匹配),看起来盐字节是 base64 编码的主要问题。您创建的两个字符串实际上具有完全相同的 base64 解码值(请参阅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] "$2a$10$XBGMfrY0DIVHX3KZVwKmM."
(my_salt_2 <- gensalt(10))
# [1] "$2a$10$NM8t5AsKmHJHs0d/hIFlbe"

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

【讨论】:

以上是关于更改盐没有效果:为啥散列密码不会因不同的盐而改变?的主要内容,如果未能解决你的问题,请参考以下文章

PHP密码哈希(),默认或自定义盐? [复制]

为啥 Ruby 的 bcrypt 库在哈希中包含明文中的盐? [复制]

用户密码盐的最佳长度是多少? [关闭]

md5 为啥 加盐

为哈希隐藏盐的必要性

bcrypt 哈希究竟如何防止彩虹表查找?