3

I have below code in java documentation (it takes secret_key and data as input) :

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")

after doing some RnD online , i wrote equivalent python to :

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

but on doing a post request with this signature value in header, i am getting

ValueError: Invalid header value 'XXXXXXXXXX'

is my python equivalent correct? it would be great help if someone can explain!

EDIT

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]:
NoobEditor
  • 15,563
  • 19
  • 81
  • 112

3 Answers3

1

Referrring to this thread :

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

minor tweeking for sha1, below is simple equivalent :

In [13]: print hmac.new(secret_key, data, hashlib.sha1).hexdigest()
2b565c0476eed0f350ddb3a2852a4cab91281bdc
Community
  • 1
  • 1
NoobEditor
  • 15,563
  • 19
  • 81
  • 112
0

pycrypto has a hash function https://pypi.python.org/pypi/pycrypto

because of ValueError: Invalid header value 'XXXXXXXXXX' see this thread ValueError: Invalid header value 'H2O Python client/2.7.9 (default, Apr 2 2015, 15:33:21) \n[GCC 4.9.2]'

maybe the header in your post is not compatible with the library you use for the post

what libraries do you import in the python code ?

Community
  • 1
  • 1
ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • to get the same result the algorithms have to be equal down to bit level (**endianness** and so on) normally you could use a debugger (pdb, jdb) to step through each operation in the algorithm and see where the difference occurs. See this thread for the source code for javax.crypto http://stackoverflow.com/questions/18181023/javax-crypto-jdk-source-code-again (java is always big-endian afaik) – ralf htp Feb 17 '16 at 20:02
  • why would i use some other language in my program when the same feature is present in my language? – NoobEditor Feb 17 '16 at 20:22
0

if you want it easy try this: https://pythonhosted.org/pycrypto/Crypto.Hash.HMAC-module.html

maybe the encoding influences the result, [UTF-8] then [base-64]

ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • 1
    getting `ec0e4e884b0056d817efb56ab5920509` as output, so not correct, also, why not edit existing answer rather than posting a new one? – NoobEditor Feb 17 '16 at 19:44