我们的应用使用库SecureHash对象来创建单向密码:https://github.com/nremond/pbkdf2-scala/blob/master/src/main/scala/io/github/nremond/SecureHash.scala
现在我的问题是Go语言中的代码返回-1
进行密码检查。
package main
import (
"bytes"
"crypto/rand"
"crypto/sha512"
"fmt"
"golang.org/x/crypto/pbkdf2"
"math/big"
"strings"
)
func main() {
iteration := 25000
// Hash User input
password := []byte("123")
salt := "yCyQMMMBt1TuPa1F9FeKfT0yrNIF8tLB"
key := pbkdf2.Key(password, []byte(salt), iteration, sha512.Size, sha512.New)
// COMPARE PASSWORD fetched from DB
// 123 hash in scala
tokenS := strings.Split("$pbkdf2-sha512$25000$yCyQMMMBt1TuPa1F9FeKfT0yrNIF8tLB$TtQt5BZLs4qlA0YAkcGukZwu7pkxOLcxwuoQB3qNtxM", "$")
passwordHashInDatabase := tokenS[4]
out := bytes.Compare(key, []byte(passwordHashInDatabase))
fmt.Println("out: ", out)
}
2条答案
按热度按时间ee7vknir1#
你有几个问题:
pbkdf2.Key()
之前,你并没有对salt进行base64解码;在将从数据库中获取的密钥与pbkdf2.Key()
的结果进行比较之前,你也没有对从数据库中获取的密钥进行base64解码;还要注意的是,Scala实现在base64解码/编码之前/之后会进行一些字符替换,这也需要在Go实现中复制。createHash()
方法有一个dkLength
参数,默认值为32
,而Go实现中提供的是sha512.Size
的结果,结果是64
,不匹配。我知道使用默认值是因为数据库中的值是32字节长。下面是一个匆忙修改的实现:
输出:
Go Playground
rkttyhzu2#
验证失败,原因如下:
可能的修复方法是:
虽然此代码适用于此特定令牌,但通常修改后的Base64应用于
.
而非+
(因此,如果存在.
,则必须在Base64解码之前将其替换为+
)且不使用填充(后者是在上述代码片段中使用base64.RawStdEncoding
的原因)。注意,Go语言(passlib package)有一个 passlib 实现,但它似乎使用了默认值(例如pbkdf 2-sha 512的输出大小为64字节),因此不能直接在这里应用。
然而,此实现可以用作您自己实现的蓝图(例如,关于Base64编码、s.
Base64Decode()
、* 恒定时间比较 *、s.SecureCompare()
、防止边信道攻击等)。