加密 – 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) 这些显然不会产生导致验证失败的相同结果. 有三个类似的论点,像这样的相同类型,这样的错误并不太令人惊讶.也许值得一看,你是否可以重组一些东西让类型系统捕获这类错误? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |