【问题标题】:java equivalent to python for hashingjava相当于python的散列
【发布时间】:2016-05-29 15:29:45
【问题描述】:

我在 java 文档中有以下代码(它需要 secret_keydata 作为输入):

javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA1")
mac.init(new javax.crypto.spec.SecretKeySpec(secret_key.getBytes(), "HmacSHA1"))
byte[] hexBytes = new org.apache.commons.codec.binary.Hex().encode(mac.doFinal(data.getBytes()))
String signature = new String(hexBytes, "UTF-8")

在网上做了一些 RnD 之后,我写了等效的 python 到:

decodedKey = secret_key.decode("hex")
hmac_val = hmac.new(decodedKey, data.encode('UTF-8'), hashlib.sha1)
signature = hmac_val.digest().encode('base64')

但是在标题中使用此签名值进行发布请求时,我得到了

ValueError: 无效的标头值 'XXXXXXXXXX'

我的 python 等价物是否正确?如果有人能解释一下,那将是很大的帮助!

编辑

Java

public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
        String secret_key = "c84766ca4a3ce52c3602bbf02ad1f7";
        String data = "some data";
        javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA1");
        mac.init(new javax.crypto.spec.SecretKeySpec(secret_key.getBytes(), "HmacSHA1"));
        byte[] hexBytes = new org.apache.commons.codec.binary.Hex().encode(mac.doFinal(data.getBytes()));
        String signature = new String(hexBytes, "UTF-8");
        System.out.println("signature : "+signature);
 }

o/p

signature : 2b565c0476eed0f350ddb3a2852a4cab91281bdc

Python:

In [1]: import hmac

In [2]: import hashlib

In [3]: secret_key = "c84766ca4a3ce52c3602bbf02ad1f7"

In [4]: data = "some data"

In [5]: decodedKey = secret_key.decode("hex")

In [6]: hmac_val = hmac.new(decodedKey, data.encode('UTF-8'), hashlib.sha1)

In [7]: signature = hmac_val.digest().encode('base64')

In [8]: signature
Out[8]: '3qE5SqSdvBEJcy8mSF+srqNXCd4=\n'

In [9]:

【问题讨论】:

  • 犯错是人类的原谅神 :)
  • 贴出两者的实际输出。
  • 我的第一个猜测是您正在散列的数据在两个平台上的表示方式不同。为每一个提供相同的预生成字节序列。
  • @chrylis :添加编辑,请参阅

标签: java python hash hmac hmacsha1


【解决方案1】:

参考这个帖子:

Java method which can provide the same output as Python method for HMAC-SHA256 in Hex

sha1 的小调整,下面是简单的等价物:

In [13]: print hmac.new(secret_key, data, hashlib.sha1).hexdigest()
2b565c0476eed0f350ddb3a2852a4cab91281bdc

【讨论】:

    【解决方案2】:

    pycrypto有一个哈希函数https://pypi.python.org/pypi/pycrypto

    因为 ValueError: Invalid header value 'XXXXXXXXXX' 看到这个帖子ValueError: Invalid header value 'H2O Python client/2.7.9 (default, Apr 2 2015, 15:33:21) \n[GCC 4.9.2]'

    也许您帖子中的标题与您用于帖子的库不兼容

    你在 python 代码中导入了哪些库?

    【讨论】:

    • 为了获得相同的结果,算法必须等于位级别(endianness 等等),通常你可以使用调试器(pdb,jdb)来逐步执行算法中的每个操作,看看差异发生在哪里。有关 javax.crypto stackoverflow.com/questions/18181023/… 的源代码,请参见此线程(java 始终为 big-endian afaik)
    • 当我的语言中存在相同的功能时,为什么我要在我的程序中使用其他语言?
    【解决方案3】:

    如果你想简单,试试这个:https://pythonhosted.org/pycrypto/Crypto.Hash.HMAC-module.html

    也许编码会影响结果,[UTF-8] 然后 [base-64]

    【讨论】:

    • 得到ec0e4e884b0056d817efb56ab5920509 作为输出,所以不正确,为什么不编辑现有答案而不是发布新答案?
    猜你喜欢
    • 2011-03-13
    • 2018-06-15
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    相关资源
    最近更新 更多