Search code examples
pythonhmaccryptojs

CryptoJS HmacSHA256 Encryption results differ from Python


CryptoJS encrypted string can pass different parameters in python can only pass a string? How to implement the second CryptoJS implementation in python ,how to get clientKey2,This will only give the first result.Thanks!

> saltedPassword=CryptoJS.PBKDF2("key", "salt", {keySize: 8,iterations:500,hasher: CryptoJS.algo.SHA256});    
> clientKey1=CryptoJS.HmacSHA256(saltedPassword.toString(), "Client Key")
> clientKey2=CryptoJS.HmacSHA256(saltedPassword, "Client Key")
> clientKey1.toString()
> "857ef8988876a3bb6bcadb85ca257787074e73e830d7dc14c1f838ba46aef1f5"
> clientKey2.toString()
> "9a8574da9b276ee1162dcb92071df587f4513bc03060bda1e9b3897d46233416"
> saltedPassword.toString()
> "6e441ccd26e6b35198b4b17457dc0266d36b751d0062b5850b0e302ceb1d6dcc"

i use this way can get clientKey1,

import hashlib
import hmac

def HmacSHA256(k,v):
    message = bytes(k).encode('utf-8')
    secret = bytes(v).encode('utf-8')
    signature = hmac.new(secret, message, digestmod=hashlib.sha256).hexdigest()
    return signature

signature = HmacSHA256("6e441ccd26e6b35198b4b17457dc0266d36b751d0062b5850b0e302ceb1d6dcc","Client Key")

print signature

How to get the second result in Python,Thanks!


Solution

  • To get the desired clientKey2 you need to encode the hex digits of your saltedPassword string to bytes. One way to do that which works on both Python 2 & Python 3 is to use binascii.unhexlify.

    Your HmacSHA256 function is a bit odd. It won't work on Python 3, since bytes objects don't have an .encode method. In Python 2, bytes is just a synonym for str.

    Anyway, here's some code that works on both Python 2 & Python 3.

    from __future__ import print_function
    import hashlib
    import hmac
    import binascii
    
    key = "Client Key".encode()
    salted = "6e441ccd26e6b35198b4b17457dc0266d36b751d0062b5850b0e302ceb1d6dcc"
    raw = binascii.unhexlify(salted)
    
    signature = hmac.new(key, salted.encode(), digestmod=hashlib.sha256).hexdigest()
    print(signature)
    
    signature = hmac.new(key, raw, digestmod=hashlib.sha256).hexdigest()
    print(signature)
    

    output

    857ef8988876a3bb6bcadb85ca257787074e73e830d7dc14c1f838ba46aef1f5
    9a8574da9b276ee1162dcb92071df587f4513bc03060bda1e9b3897d46233416
    

    The output is identical on Python 2 & Python 3.

    BTW, it would be simpler to do this task in Python 3, which makes a clean distinction between text and byte strings. Also, the Python 3 hashlib module has a pbkdf2 function.