存储 crypto/rand 生成的字符串问题
Storing crypto/rand generated string issues
所以我有以下 go file(s) 作为我项目的一部分用于散列密码,我还编写了一些据我所知尚未失败的测试。
目前的问题是我正在尝试将密码和盐作为字符串存储在某些数据库中,每次我检索它们以与另一个字符串进行比较时,我都会不断从 golang 的 bcrypt 包中获取图片中的消息.我写的测试 运行 很好并且产生了适当的效果。我会提供一个 go playground link 但 bcrypt 包是标准库的一部分。
我知道 crypto/rand
中的乱码与最初看起来几乎相同,但我不确定数据库中是否有任何更改。我正在使用redis fyi。
编辑:根据@3of3 的要求,我包含了我项目中的DAO 代码。仅 bcrypt 解决方案也适用于此代码,但正如我在评论中所述,我的目标是坚持 Mozilla 的指南。
您似乎忘记了生成的哈希是十六进制编码的,因此当将 []byte 变量转换为字符串时,您会得到一些奇怪的东西。使用十六进制包你可以创建你想要的实际字符串:
hex.EncodeToString(hash)
salt 不会通过 JSON 编码/解码往返,因为 salt 不是有效的 UTF8。
有几种方法可以解决此问题:
- 十六进制或 base64 编码/解码哈希器中的盐。
- 在整个代码中使用 []byte 类型作为 salt。 JSON 编码器使用 base64 对 []byte 值进行编码。
- 使用 gob 编码器而不是 JSON 编码器。
Mozilla 建议将额外的 salt 与 bcrypted 密码分开存储。通过使用 bcrypted 密码存储额外的盐,系统并不比单独使用 bcrypt 更安全。
要对盐进行十六进制编码,请更改
return string(p), string(salt), nil
到
return string(p), hex.EncodeToString(salt), nil
并更改
s := []byte(salt)
到
s, err := hex.DecodeString(salt)
if err != nil {
return err
}
所以我有以下 go file(s) 作为我项目的一部分用于散列密码,我还编写了一些据我所知尚未失败的测试。
目前的问题是我正在尝试将密码和盐作为字符串存储在某些数据库中,每次我检索它们以与另一个字符串进行比较时,我都会不断从 golang 的 bcrypt 包中获取图片中的消息.我写的测试 运行 很好并且产生了适当的效果。我会提供一个 go playground link 但 bcrypt 包是标准库的一部分。
我知道 crypto/rand
中的乱码与最初看起来几乎相同,但我不确定数据库中是否有任何更改。我正在使用redis fyi。
编辑:根据@3of3 的要求,我包含了我项目中的DAO 代码。仅 bcrypt 解决方案也适用于此代码,但正如我在评论中所述,我的目标是坚持 Mozilla 的指南。
您似乎忘记了生成的哈希是十六进制编码的,因此当将 []byte 变量转换为字符串时,您会得到一些奇怪的东西。使用十六进制包你可以创建你想要的实际字符串:
hex.EncodeToString(hash)
salt 不会通过 JSON 编码/解码往返,因为 salt 不是有效的 UTF8。
有几种方法可以解决此问题:
- 十六进制或 base64 编码/解码哈希器中的盐。
- 在整个代码中使用 []byte 类型作为 salt。 JSON 编码器使用 base64 对 []byte 值进行编码。
- 使用 gob 编码器而不是 JSON 编码器。
Mozilla 建议将额外的 salt 与 bcrypted 密码分开存储。通过使用 bcrypted 密码存储额外的盐,系统并不比单独使用 bcrypt 更安全。
要对盐进行十六进制编码,请更改
return string(p), string(salt), nil
到
return string(p), hex.EncodeToString(salt), nil
并更改
s := []byte(salt)
到
s, err := hex.DecodeString(salt)
if err != nil {
return err
}