【问题标题】:Python vs Go Hashing DifferencesPython vs Go 哈希差异
【发布时间】:2015-03-21 14:14:00
【问题描述】:

我有一个 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
}

还有一个 Python (2.7) 程序试图重现 Go 代码(使用 crypto/hmac

import hashlib
val =  u'nJ1m4Cc3'
hasher = hashlib.new("sha1", val)
print hasher.hexdigest()
# d67c1f445987c52bceb8d6475c30a8b0e9a3365d

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

import hmac
val = 'nJ1m4Cc3'
h = hmac.new("sha1", val)
print h.hexdigest()
# d34435851209e463deeeb40cba7b75ef

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

【问题讨论】:

  • python 中的val不是字节...试试val = b'nJ1m4Cc3'
  • 我的答案中包含了一种 Python 方法,可以重现您现在在 Go 中显示的内容。 hmac.new("sha1", val) 是错误的:它提供了"sha1"key,并且没有指定正确的摘要构造函数,因此该方法实际上在内部使用了 md5。您只需要仔细阅读文档并了解msgkeydigestmod 参数在hmac.new() 签名中的含义。 docs.python.org/2/library/hmac.html
  • 不客气,这是再次使用 Go 的好机会,我已经在我的系统上设置了一段时间 :-)。而且,以防万一,不要忘记接受答案:-)。

标签: python hash go cryptography sha1


【解决方案1】:

你必须确保

  • 两种情况下的输入是等效的,并且
  • 两种场景的处理方式是等价的。

在这两种情况下,输入都应该是相同的二进制 blob。在您的 Python 程序中,您定义了一个 unicode 对象,并且您不控制它的二进制表示。将u 前缀替换为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))
}

测试和输出:

go run hashit.go
d67c1f445987c52bceb8d6475c30a8b0e9a3365d

这会重现您的第一个 Python sn-p 创建的内容。

编辑:我稍微简化了 Go 代码,而不是让 Python 看起来更优雅。 Go 在这里也很优雅:-)。

鉴于 Go 是参考

import hmac
import hashlib

data = b'nJ1m4Cc3'
h = hmac.new(key=data, digestmod=hashlib.sha1)
print h.hexdigest()

测试和输出:

python hashit.py
f7c0aebfb7db2c15f1945a6b7b5286d173df894d

这会重现您的 Go sn-p 创建的内容。但是,当使用空消息时,我不确定 HMAC 的加密意义。

【讨论】:

  • 我正在尝试与使用github.com/yhat/phash 散列的现有密码以及使用hasher := hmac.New(sha1.New, val) 行的节点密码散列保持一致。不过谢谢!
猜你喜欢
  • 2023-03-22
  • 2011-08-08
  • 2023-03-31
  • 1970-01-01
  • 2018-02-11
  • 2017-08-02
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多