简体   繁体   中英

HMACSHA265 output difference between CryptoJS and Python

I have a working CryptoJS signing that I need to translate to Python in order to run it in our testcases. The problem is that when I input the same parameter values and use the same algorithm it returns different resulting signing hashes in Python vs CryptoJS.

Code with CryptoJS:

<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<script>
window.onload = function(){

    var privateKey = "F2FD99BA2BA7335BF0336CA0A5714F02042D073D3742A312";
    var targetSystem = "mydomain.de";
    
    var preDerivedKey = GetPreDerivedKey(privateKey, targetSystem, CurrentUtcDateTimeStamp());
}   

function CurrentUtcDateTimeStamp()
{
    // For debugging, set to 0 for now
    return "0";
};

function Encrypt(data, password)
{
    var hash = CryptoJS.HmacSHA256(data, password);
    
    console.log("Function Encrypt (using data '" + data + "' and password '" + password + "'), Hash is: " + hash);
    return hash;
};

function GetPreDerivedKey(privateKey, targetSystem, timestamp)
{
    console.log("Function GetPreDerivedKey received: privateKey '" +  privateKey + "', targetSystem '" + targetSystem + "', timestamp '" + timestamp + "'");
    var derivedKey = Encrypt(targetSystem, privateKey);
    derivedKey = Encrypt(timestamp, derivedKey);
    return derivedKey;
};
</script>
</html>

Code in Python:

import hashlib
import hmac

privateKey = "F2FD99BA2BA7335BF0336CA0A5714F02042D073D3742A312"
targetSystem = "mydomain.de"

def CurrentUtcDateTimeStamp():
    return "0"

def Encrypt(data, password):
    hash = hmac.new(password.encode('utf-8'),msg=data.encode('utf-8'),digestmod=hashlib.sha256).hexdigest()
    
    print("Function Encrypt (using data '" + data + "' and password '" + password + "'), Hash is:")
    
    hexstring = ""
    for bytes in hash:
        hexstring += str(bytes)
    print(hexstring)

    return hash

def GetPreDerivedKey(privateKey, targetSystem, timestamp):
    print("Function GetPreDerivedKey received: privateKey '" +  privateKey + "', targetSystem '" + targetSystem + "', timestamp '" + timestamp + "'")
    derivedKey = Encrypt(targetSystem, privateKey)
    derivedKey = Encrypt(timestamp, derivedKey)
    return derivedKey

# Signing
preDerivedKey = GetPreDerivedKey(privateKey, targetSystem, CurrentUtcDateTimeStamp());

Console output of both codes when executed.

PY

Function GetPreDerivedKey received: privateKey 'F2FD99BA2BA7335BF0336CA0A5714F02042D073D3742A312', targetSystem 'mydomain.de', timestamp '0'
Function Encrypt (using data 'mydomain.de' and password 'F2FD99BA2BA7335BF0336CA0A5714F02042D073D3742A312'), Hash is:
3c0f696075960ec05e0b0ace52594cd49855aff052489911608c6b9ea37a553e
Function Encrypt (using data '0' and password '3c0f696075960ec05e0b0ace52594cd49855aff052489911608c6b9ea37a553e'), Hash is:
48e5d0f3f6ac4563b765ff0caa9b09ec34cddbbc247185d50785a2b1e8b6eb59

JS

Function GetPreDerivedKey received: privateKey 'F2FD99BA2BA7335BF0336CA0A5714F02042D073D3742A312', targetSystem 'mydomain.de', timestamp '0' 
Function Encrypt (using data 'mydomain.de' and password 'F2FD99BA2BA7335BF0336CA0A5714F02042D073D3742A312'), Hash is:
3c0f696075960ec05e0b0ace52594cd49855aff052489911608c6b9ea37a553e
Function Encrypt (using data '0' and password '3c0f696075960ec05e0b0ace52594cd49855aff052489911608c6b9ea37a553e'), Hash is:
577ae299e95e289395c4614412b60dc527bdba2066ccd3e76af0e4cbb4cc4495

You can see the difference in the last line: 48e5d0f3f6ac4563b765ff0caa9b09ec34cddbbc247185d50785a2b1e8b6eb59 vs 577ae299e95e289395c4614412b60dc527bdba2066ccd3e76af0e4cbb4cc4495

Interestingly enough, the first iteration is still correct and shows the same result. Only the second iteration is different.

Any help would be appreciated, thanks!

Have you tried to return the hexstring instead of the hash in you python "Encrypt" function?

Got it running through the following code and thanks to Topaco's input:

targetSystem = "mydomain.de"
privateKey = "F2FD99BA2BA7335BF0336CA0A5714F02042D073D3742A312"

def CurrentUtcDateTimeStamp():
    return "0"

def Encrypt(data, password):
    
    print("Function Encrypt")

    # Convert the input parmeters depending on their data type. They are expected as byte or bytearray.
    if(isinstance(data, str)):
        print("Data: '" + data + "' (converted from string to byte)")
        data = data.encode("utf-8")
    if(isinstance(password, str)):
        print("Password '" + password + "' (converted from string to byte)")
        password = password.encode("utf-8")
    elif(isinstance(password, bytearray)):
        print("Password '" + str(password.hex()) + "'")

    hash = hmac.new(msg=data,key=password,digestmod=hashlib.sha256).hexdigest()

    # Convert hex-encoded data into a byte array
    hash_bytes = bytearray.fromhex(hash)

    # Print result
    hexstring = ""
    for bytes in hash:
        hexstring += str(bytes)
    print("Result:" + hexstring + "\n")
    return hash_bytes

def GetPreDerivedKey(privateKey, targetSystem, timestamp):
    print("Function GetPreDerivedKey received: privateKey '" +  privateKey + "', targetSystem '" + targetSystem + "', timestamp '" + timestamp + "'")
    print("")
    derivedKey = Encrypt(targetSystem, privateKey)
    derivedKey = Encrypt(timestamp, derivedKey)
    return derivedKey

# Signing
preDerivedKey = GetPreDerivedKey(privateKey, targetSystem, CurrentUtcDateTimeStamp());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM