Python vs Go Hashing差异

eri*_*ang 1 python hash cryptography sha1 go

我有一个Go程序

package main

import (
    "crypto/hmac"
    "crypto/sha1"
    "fmt"
)

func main() {
    val := []byte("nJ1m4Cc3")
    hasher := hmac.New(sha1.New, val)
    fmt.Printf("%x\n", hasher.Sum(nil))
    // f7c0aebfb7db2c15f1945a6b7b5286d173df894d
}
Run Code Online (Sandbox Code Playgroud)

和Python(2.7)程序试图重现Go代码(使用crypto/hmac)

import hashlib
val =  u'nJ1m4Cc3'
hasher = hashlib.new("sha1", val)
print hasher.hexdigest()
# d67c1f445987c52bceb8d6475c30a8b0e9a3365d
Run Code Online (Sandbox Code Playgroud)

使用该hmac模块给出了不同的结果,但仍然与Go代码不同.

import hmac
val = 'nJ1m4Cc3'
h = hmac.new("sha1", val)
print h.hexdigest()
# d34435851209e463deeeb40cba7b75ef
Run Code Online (Sandbox Code Playgroud)

为什么这些在同一输入上使用相同的哈希时会打印不同的值?

Jan*_*cke 6

你必须确保这一点

  • 两种情况下的输入都是等价的
  • 两种情况下的处理方法是等效的.

在这两种情况下,输入应该是相同的二进制blob.在Python程序中,您定义了一个unicode对象,并且您无法控制其二进制表示.u用a 替换前缀b,你很好(这是在Python 2.7和3中定义字节序列的明确方法).这不是实际问题,但最好在此明确说明.

问题是你在Go和Python实现中应用了不同的方法.

鉴于Python是参考

在Go中,根本不需要导入"crypto/hmac",在Python中只需构建数据的SHA1哈希值即可.在Go中,等效的是:

package main

import (
    "crypto/sha1"
    "fmt"
)

func main() {
    data := []byte("nJ1m4Cc3")
    fmt.Printf("%x", sha1.Sum(data))
}
Run Code Online (Sandbox Code Playgroud)

测试和输出:

go run hashit.go
d67c1f445987c52bceb8d6475c30a8b0e9a3365d
Run Code Online (Sandbox Code Playgroud)

这将再现您的第一个Python代码段创建的内容.

编辑:我已经简化了Go代码,不会让Python看起来更优雅.Go在这里也很优雅:-).

鉴于Go是参考

import hmac
import hashlib

data = b'nJ1m4Cc3'
h = hmac.new(key=data, digestmod=hashlib.sha1)
print h.hexdigest()
Run Code Online (Sandbox Code Playgroud)

测试和输出:

python hashit.py
f7c0aebfb7db2c15f1945a6b7b5286d173df894d
Run Code Online (Sandbox Code Playgroud)

这将再现Go代码段创建的内容.但是,当使用空消息时,我不确定HMAC的加密重要性.