为了账号安全,请及时绑定邮箱和手机立即绑定

密码哈希字符串编码的标准是什么?

密码哈希字符串编码的标准是什么?

Go
12345678_0001 2023-02-06 19:32:13
我在询问密码散列后使用的格式并准备存储。美元符号$注释似乎很普遍。是否在某个地方的标准中进行了描述(包括算法的标识符)?例如,当使用 Go with 时golang.org/x/crypto/bcrypt,它会给出这样一个编码字符串(playground):func main() {    h, err := bcrypt.GenerateFromPassword([]byte("foo"), bcrypt.DefaultCost)    if err != nil {        panic(err)    }    fmt.Printf("%s", h)    // Output: $2a$10$g1d5KuvDIrRoUyWL2BQs7uLOWCzlM.zqbRm8o364u20p20YNmJ.Ve}但是,其他散列包scrypt(例如)argon2只返回结果散列。使用argon2shell 命令,返回一个编码字符串:echo "foo" | argon2 saltsaltType:           Argon2iIterations:     3Memory:         4096 KiBParallelism:    1Hash:           d9e4f94546b9e5b0cfb2dbf9dad81d41371845d8b6a8c25ce7caf23e13f1ef72Encoded:        $argon2i$v=19$m=4096,t=3,p=1$c2FsdHNhbHQ$2eT5RUa55bDPstv52tgdQTcYRdi2qMJc58ryPhPx73I0.005 secondsVerification ok我找到了一篇解释这种编码的 Go / argon2specific博客文章,到目前为止还不错我发现的变化我的麻烦在于美元分隔字符串的定义、我发现的可移植性和变体。glibc该man 3 crypt页面提供了一些指示。有一个标识符表:              ID   Method              ───────────────────────────────────────────────────────────              1    MD5              2a   Blowfish (not in mainline glibc; added in some Linux                   distributions)              5    SHA-256 (since glibc 2.7)              6    SHA-512 (since glibc 2.7)但这不包括较新的类型,例如argon2ior scrypt。然后是示例字符串:$id$salt$encrypted$id$rounds=yyy$salt$encrypted后者仅在 Glibc 2.7 之后才受支持。密码虽然bcrypt使用2a来自 Glibc 的 (blowfish) 标识符,但其编码似乎与上面的示例略有不同:$2a$10$g1d5KuvDIrRoUyWL2BQs7uLOWCzlM.zqbRm8o364u20p20YNmJ.Ve$id$cost$<dot seperated line of what exactly?>氩2Argon2 使用 5 个字段和一个全名标识符,例如argon2$argon2i$v=19$m=4096,t=3,p=1$c2FsdHNhbHQ$2eT5RUa55bDPstv52tgdQTcYRdi2qMJc58ryPhPx73I$id$version$parameters$salt$encrypted为什么?我想编写一个以算法不可知的方式散列和验证密码的包。允许消费者在不重构代码的情况下更改参数和算法。因此,在验证过程中,包应该能够断言存储密码时使用的算法。如果存储的参数或算法版本与当前使用的版本不同,则重新散列密码并返回新的编码字符串。作为奖励,我希望该软件包能够重新散列可能由较旧的(未运行的)应用程序存储的“旧”密码。例如,md5。为了做到这一切,我想对存储格式本身有更深入的了解。
查看完整描述

1 回答

?
慕神8447489

TA贡献1780条经验 获得超1个赞

密码哈希字符串编码的标准是什么?

空无一人。

嘿,这是一个简单的答案!单击“发布您的答案”

好吧,不幸的是,虽然上面的说法是正确的,但值得庆幸的是,有些人已经费了很大的劲收集了很多关于所有使用变化的信息。

特别是,Python 的Passlib库的作者(它基本上做你想做的事情)已经写了一个关于他们称之为模块化地穴格式的页面,他们称之为“不是标准”。以下是该页面的一些精选引述 [粗体斜体强调我的]:

但是,没有描述此格式的官方规范文档。也没有标识符的中央注册表或实际规则。模块化的 crypt 格式更像是一个临时的想法,而不是一个真正的标准。

[模块化地穴格式 – 概述]

不幸的是,没有这种格式的规范文档。相反,它仅以事实上的形式存在

首次引入 MCF 时,大多数方案选择单个数字作为其标识符(例如$1$,对于md5_crypt)。因此,一些较旧的系统在尝试区分哈希值时仅查看第一个字符。

大多数模块化 crypt 格式散列都遵循此约定,尽管有些(如bcrypt省略$了配置和摘要之间的分隔符。

[T]这里没有关于配置字符串是否应该$在末尾包含尾随的标准

[模块化地穴格式 – 要求]

请注意,模块化地穴格式不是规范或标准。它描述了在野外使用的各种不同格式。密码哈希竞赛 (PHC)组织者试图制定一个规范,称为PHC 字符串格式。但是,PHC 不是具有任何权威的正式标准组织。它只是一群松散的密码学家。虽然他们建议每个新的密码哈希函数都应该使用 PHC 字符串格式,但他们只能强制要求提交给密码哈希竞赛的密码哈希函数使用 PHC 字符串格式。

无论哪种方式,PHC 字符串格式仅适用于新的密码哈希函数,不适用于现有的。

虽然我强烈建议您应该对生成的任何输出使用 PHC 字符串格式,但您仍然需要处理各种不同格式的输入,包括像这样的一些 gem

cta_pbkdf2_sha1dlitz_pbkdf2_sha1都使用相同的标识符。虽然存在其他内部差异,但可以通过以下事实快速区分两者:cta 哈希总是以 结尾=,而 dlitz 哈希根本不包含=


查看完整回答
反对 回复 2023-02-06
  • 1 回答
  • 0 关注
  • 79 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信