我在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 web-server)中,我接受来自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
答案 0 :(得分:3)
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)
}