'Unable to match results of php hash_hmac() and coldfusion hmac()
I am working on encrypting a URL and converting a working script from PHP to ColdFusion. I have completed 95% of the work but I am stuck at this point after trying many solutions available on StackOverflow. My results are still not matching. I confirmed the saltBin
and keyBin
values are the same on both scripts. Please have a look.
PHP version
$saltBin = R�k��E�x^ �O<�-�7J=S�z��� �;
$keyBin = �;B��|� �0U,��h�NS+��.��G���
res = hash_hmac('sha256', $saltBin, $keyBin);
result
39ddcd6156a30fdcebc9fbf5dd59a0ef4f47e27841bbc12ce72b64a0a63c0324
Coldfusion version
<cfset res = hmac(saltBin,keyBin,"HMACSHA256")>
result
30A658BEB3965C2D7D27A3F717FB6C13B05ED44E8B2A5A7FEBB9B57887CF57A0
I have tried the following solutions
ColdFusion equivalent to PHP hash_hmac
coldfusion hashing and difference between hmacSHA256 and SHA256
Update:
Below is an abbreviated version of the PHP version
$key = '943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881';
$salt = '520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5';
$keyBin = pack("H*" , $key);
$saltBin = pack("H*" , $salt);
$path = "/rs:fill:300:300:1/g:no/aHR0cDovL2ltZy5leGFtcGxlLmNvbS9wcmV0dHkvaW1hZ2UuanBn.png";
echo hash_hmac('sha256', $saltBin.$path, $keyBin);
Result: 7062c2b5786c82de963767de4b0cdbc4e7ed7db2ce7466708bf8a28d8572888b
<cfset key = '943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881'>
<cfset salt = '520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5'>
<cfset keyBin = binaryDecode(key, 'hex')>
<cfset keyBin = toString(keyBin)>
<cfset saltBin = binaryDecode(salt, 'hex')>
<cfset saltBin = toString(saltBin)>
<cfset path = "/rs:fill:300:300:1/g:no/aHR0cDovL2ltZy5leGFtcGxlLmNvbS9wcmV0dHkvaW1hZ2UuanBn.png">
<cfset result = hmac(saltBin&path,keyBin,"HMACSHA256")>
<cfoutput>#result#</cfoutput>
Result: FFA7A526BB464CA1470F309605F1ED63832342B704F8475BFAF26CCD1092603B
Can anyone please help me in this regard?
Thanks.
Solution 1:[1]
saltBin and keyBin values are the same on both scripts
Yes, those values are the same, but the data being hashed isn't. That's why the results don't match.
The php code hashes the concatenated binary of the salt and path variables. To illustrate using a simple values:
Data | Value | Binary | Base64 |
---|---|---|---|
Salt | ab | [-85] | qw== |
Path | 123 | [49,50,51] | MTIz |
Salt + Path | n/a | [-85,49,50,51] | qzEyMw== |
Whereas the CF code uses the binary of the concatenated strings salt and path, after some very ... dubious re-encoding with ToString(). As you can see, the resulting binary is very different than what's used by php:
Data | Value | Binary | Base64 |
---|---|---|---|
Salt | ? | [-17,-65,-67] | 77+9 |
Path | 123 | [49,50,51] | MTIz |
Salt + Path | ?123 | [-17,-65,-67,49,50,51] | 77+9MTIz |
The CF code needs to concatenate the binary of the two variables. Then pass that binary to the hmac() function:
CF (see runnable example)
<cfscript>
key = '943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881';
salt = '520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5';
keyBin = binaryDecode(key, "hex");
saltBin = binaryDecode(salt, "hex");
path = "/rs:fill:300:300:1/g:no/aHR0cDovL2ltZy5leGFtcGxlLmNvbS9wcmV0dHkvaW1hZ2UuanBn.png";
pathBin = charsetDecode(path, "utf-8");
// merge binary of salt and path
combined = [];
combined.append(saltBin, true);
combined.append(pathBin, true);
result = lcase(hmac( javacast("byte[]", combined),keyBin,"HMACSHA256"));
writeDump(result);
</cfscript>
Result: 7062c2b5786c82de963767de4b0cdbc4e7ed7db2ce7466708bf8a28d8572888b
PHP (see runnable example)
<?php
$key = '943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881';
$salt = '520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5';
$keyBin = pack("H*" , $key);
$saltBin = pack("H*" , $salt);
$path = "/rs:fill:300:300:1/g:no/aHR0cDovL2ltZy5leGFtcGxlLmNvbS9wcmV0dHkvaW1hZ2UuanBn.png";
echo hash_hmac('sha256', $saltBin.$path, $keyBin);
Result: 7062c2b5786c82de963767de4b0cdbc4e7ed7db2ce7466708bf8a28d8572888b
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |