duanshang9426 2015-01-22 17:09
浏览 43
已采纳

Python与Go散列的区别

I have a Go program

package main

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

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

And a Python (2.7) program that is attempting to reproduce the Go code (using crypto/hmac)

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

Using the hmac module gives me a different result but still not the same as the Go code.

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

Why do these print different values when they use the same hash on the same input?

  • 写回答

1条回答 默认 最新

  • dongying3744 2015-01-22 17:20
    关注

    You have to make sure that

    • the input in both scenarios is equivalent and that
    • the processing method in both scenarios is equivalent.

    In both cases, the input should be the same binary blob. In your Python program you define a unicode object, and you do not take control of its binary representation. Replace the u prefix with a b, and you are fine (this is the explicit way to define a byte sequence in Python 2.7 and 3). This is not the actual problem, but better be explicit here.

    The problem is that you apply different methods in your Go and Python implementations.

    Given that Python is the reference

    In Go, no need to import "crypto/hmac" at all, in Python you just build a SHA1 hash of your data. In Go, the equivalent would be:

    package main
    
    import (
        "crypto/sha1"
        "fmt"
    )
    
    func main() {
        data := []byte("nJ1m4Cc3")
        fmt.Printf("%x", sha1.Sum(data))
    }
    

    Test and output:

    go run hashit.go
    d67c1f445987c52bceb8d6475c30a8b0e9a3365d
    

    This reproduces what your first Python snippet creates.

    Edit: I have simplified the Go code a bit, to not make Python look more elegant. Go is quite elegant here, too :-).

    Given that Go is the reference

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

    Test & output:

    python hashit.py
    f7c0aebfb7db2c15f1945a6b7b5286d173df894d
    

    This reproduces what your Go snippet creates. I am, however, not sure about the cryptographic significance of an HMAC when one does use an empty message.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 请问为什么我配置IPsec后PC1 ping不通 PC2,抓包出来数据包也并没有被加密
  • ¥200 求博主教我搞定neo4j简易问答系统,有偿
  • ¥15 nginx的使用与作用
  • ¥100 关于#VijeoCitect#的问题,如何解决?(标签-ar|关键词-数据类型)
  • ¥15 一个矿井排水监控系统的plc梯形图,求各程序段都是什么意思
  • ¥50 安卓10如何在没有root权限的情况下设置开机自动启动指定app?
  • ¥15 ats2837 spi2从机的代码
  • ¥200 wsl2 vllm qwen1.5部署问题
  • ¥100 有偿求数字经济对经贸的影响机制的一个数学模型,弄不出来已经快要碎掉了
  • ¥15 数学建模数学建模需要