加密 – Golang加密多个调用有不同的响应
发布时间:2020-12-16 09:25:18 所属栏目:大数据 来源:网络整理
导读:我遇到了一些我为密码认证库编写的Go代码的问题.一般的想法是提供2个函数,Check()和New(),它们都提供了密码和256位HMAC密钥. Check()函数还提供256位salt和256位散列,并返回一个布尔值. New()函数返回一个新的随机salt,它是相应的哈希值.这两个函数都依赖于
|
我遇到了一些我为密码认证库编写的Go代码的问题.一般的想法是提供2个函数,Check()和New(),它们都提供了密码和256位HMAC密钥. Check()函数还提供256位salt和256位散列,并返回一个布尔值. New()函数返回一个新的随机salt,它是相应的哈希值.这两个函数都依赖于辅助函数hash(),它使用scrypt进行键延长,并且可以生成输出哈希.
当我最初编写它时,这是有效的(事实证明我已经使用了早期丢失的代码修订版生成的测试数据). 我现在遇到的问题是,当提供由旧版本代码生成的数据时,Check()函数似乎工作得很好,但现在看来代码自己的New()函数生成的任何数据都失败了(两者都使用底层的hash()函数). 我知道,我应该从一开始就有git版本控制代码!我现在已经吸取了教训. 我已将函数分组并将问题快速演示到一个.go文件中,如下所示,并添加了一些输出用于调试: package main
import (
"code.google.com/p/go.crypto/scrypt"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"crypto/subtle"
"errors"
"fmt"
"io"
)
// Constants for scrypt. See code.google.com/p/go.crypto/scrypt
const (
KEYLENGTH = 32
N = 16384
R = 8
P = 1
)
// hash takes an HMAC key,a password and a salt (as byte slices)
// scrypt transforms the password and salt,and then HMAC transforms the result.
// Returns the resulting 256 bit hash.
func hash(hmk,pw,s []byte) (h []byte,err error) {
sch,err := scrypt.Key(pw,s,N,R,P,KEYLENGTH)
if err != nil {
return nil,err
}
hmh := hmac.New(sha256.New,hmk)
hmh.Write(sch)
h = hmh.Sum(nil)
hmh.Reset() // Probably not necessary
return h,nil
}
// Check takes an HMAC key,a hash to check,a password and a salt (as byte slices)
// Calls hash().
// Compares the resulting 256 bit hash against the check hash and returns a boolean.
func Check(hmk,h,s []byte) (chk bool,err error) {
// Print the input hash
fmt.Printf("Hash: %xnHMAC: %xnSalt: %xnPass: %xn",hmk,[]byte(pw))
hchk,err := hash(hmk,s)
if err != nil {
return false,err
}
// Print the hash to compare against
fmt.Printf("Hchk: %xn",hchk)
if subtle.ConstantTimeCompare(h,hchk) != 1 {
return false,errors.New("Error: Hash verification failed")
}
return true,nil
}
// New takes an HMAC key and a password (as byte slices)
// Generates a new salt using "crypto/rand"
// Calls hash().
// Returns the resulting 256 bit hash and salt.
func New(hmk,pw []byte) (h,s []byte,err error) {
s = make([]byte,KEYLENGTH)
_,err = io.ReadFull(rand.Reader,s)
if err != nil {
return nil,nil,err
}
h,err = hash(pw,err
}
fmt.Printf("Hash: %xnSalt: %xnPass: %xn",[]byte(pw))
return h,nil
}
func main() {
// Known values that work
pass := "pleaseletmein"
hash := []byte{
0x6f,0x38,0x7b,0x9c,0xe3,0x9d,0x9,0xff,0x6b,0x1c,0xc,0xb5,0x1,0x67,0x1d,0x11,0x8f,0x72,0x78,0x85,0xca,0x6,0x50,0xd0,0xe6,0x8b,0x12,0xf4,0xcb,0x29,}
salt := []byte{
0x77,0xd6,0x57,0x62,0x65,0x20,0x3b,0x19,0x42,0xc1,0x8a,0x4,0x97,0x48,0x44,0x7,0x4a,0xe8,0xdf,0xfa,0x3f,0xed,0xe2,0x14,0xfc,}
hmac := []byte{
0x70,0x23,0xbd,0x3a,0xfd,0x73,0x46,0xcd,0x81,0xeb,0xa8,0xfb,0xba,0x90,0x4f,0x8e,0x3e,0xa9,0x43,0xf6,0x54,0x5d,0xa1,0xf2,}
// Check the known values. This Works.
fmt.Println("Checking known values...")
chk,err := Check(hmac,hash,[]byte(pass),salt)
if err != nil {
fmt.Printf("%sn",err)
}
fmt.Printf("%tn",chk)
fmt.Println()
// Create new hash and salt from the known HMAC and Salt
fmt.Println("Creating new hash and salt values...")
h,err := New(hmac,[]byte(pass))
if err != nil {
fmt.Printf("%sn",err)
}
// Check the new values. This Fails!
fmt.Println("Checking new hash and salt values...")
chk,err = Check(hmac,s)
if err != nil {
fmt.Printf("%sn",chk)
}
我在Linux 64bit和Windows8 64bit上都尝试了这个,但两者都失败了. 任何帮助将非常感激!就像我说的那样,我确实在某些方面有这个工作,但我似乎已经在某个地方打破了它.我通常只发现它在编写单元测试时不起作用……我想这就是他们的目的! 谢谢, 麦克风. 解决方法
你似乎已经在你的一个函数中颠倒了hash()的参数.在Check()中,您有:
hchk,s) 在New()中你有: h,s) 这些显然不会产生导致验证失败的相同结果. 有三个类似的论点,像这样的相同类型,这样的错误并不太令人惊讶.也许值得一看,你是否可以重组一些东西让类型系统捕获这类错误? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
