【问题标题】:bcrypt generates incorrect hashes - is my user-input processing correct?bcrypt 生成不正确的哈希 - 我的用户输入处理是否正确?
【发布时间】:2018-05-10 12:29:09
【问题描述】:

我用 Go 编写了一个简短的程序,用于从通过 stdin 提供的密码生成 bcrypt 密码哈希。下面的小例子:

package main

import (
    "bufio"
    "fmt"
    "golang.org/x/crypto/bcrypt"
)

func main() {

    fmt.Println("Enter password:")
    reader := bufio.NewReader(os.Stdin)
    inputPassword, _ := reader.ReadString('\n')

    inputPasswordBytes := []byte(inputPassword)
    hashBytes, _ := bcrypt.GenerateFromPassword(inputPasswordBytes, bcrypt.DefaultCost)

    hashStr := string(hashBytes)

    fmt.Println(hashStr)
}

在另一个程序(Go 网络服务器)中,我接受来自 HTTP POST 请求的用户密码,并针对使用上述代码生成并保存到启动时加载的配置文件的哈希进行测试,如下所示:

func authenticateHashedPassword(inputPassword string) bool {

    configPasswordHashBytes := []byte(server.Config.Net.Auth.Password)
    inputPasswordBytes := []byte(inputPassword)
    err := bcrypt.CompareHashAndPassword(configPasswordHashBytes, inputPasswordBytes)
    if err != nil {
        return false
    }
    return true

}

但是,当我知道 inputPassword 正确时,这会报告失败。经过一番调查后,我发现当我使用此网站测试我的值时,上面的初始 func main 生成了错误的输出:https://www.dailycred.com/article/bcrypt-calculator - 它说我生成的所有输出都与所需的密码不匹配。

当我执行[]byte(inputPassword) 时,我假设字符编码或其他细节有问题 - 它可能包括尾随行结尾吗?

很遗憾,我无法逐步调试我的程序,因为 Visual Studio Code 的 Go 语言工具和调试器不支持使用标准 IO:https://github.com/Microsoft/vscode-go/issues/219

【问题讨论】:

    标签: go stdin bcrypt


    【解决方案1】:

    bufio Reader.ReadString 方法返回直到并包括 \n 分隔符的数据。 \n 包含在密码中。使用strings.TrimSpace 修剪\n 和用户可能输入的任何空格。

    package main
    
    import (
        "bufio"
        "fmt"
        "golang.org/x/crypto/bcrypt"
    )
    
    func main() {
    
        fmt.Println("Enter password:")
        reader := bufio.NewReader(os.Stdin)
        inputPassword, _ := strings.TrimSpace(reader.ReadString('\n'), "\n"))
    
        inputPasswordBytes := []byte(inputPassword)
        hashed, _ := bcrypt.GenerateFromPassword(inputPasswordBytes, bcrypt.DefaultCost)
    
        fmt.Printf("%s\n", hashed)
    }
    

    【讨论】:

    • 我的程序省略了我在hashStr = string(hashBytes) 处所做的一行。两种情况下的输出外观(bcrypt 值的字符范围和文本长度)是相同的。
    • 当我在 Windows 上运行时,inputPassword 值包含一个尾随 \r - 所以我使用 strings.TrimSpace() 而不是 TrimSuffix
    • 原来我的真实代码中还有一个次要问题(在我发布的示例中不可见),我错误地隐藏了 inputPassword 值。考虑到编译器对其他所有内容(例如未使用的变量)的严格程度,我很惊讶 Go 并没有警告我。
    猜你喜欢
    • 2021-03-18
    • 2012-11-09
    • 2012-01-18
    • 1970-01-01
    • 2016-08-24
    • 2017-08-20
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    相关资源
    最近更新 更多