0

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

ColdFusion version

<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.

SOS
  • 6,430
  • 2
  • 11
  • 29
dev
  • 555
  • 1
  • 13
  • 31
  • We need to see the code showing how `$saltBin` and `$keyBin` are actually populated. Also, when dealing with binary, it's better to post values as base64 encoded strings [base64_encode](https://www.php.net/manual/en/function.base64-encode.php). What's the base64 encoded value of `$saltBin` and `$keyBin` ? – SOS May 09 '22 at 14:51
  • @SOS I have added the full scripts in the links at the end of the question. Please check. – dev May 09 '22 at 16:09
  • Please see https://stackoverflow.com/a/66079528/2645359 – AndreasRu May 09 '22 at 17:50
  • No idea why someone voted to close this question as "Seeking recommendations for books, tools, software libraries, and more". It's clearly about a specific code problem, with code samples and results provided. – SOS May 10 '22 at 02:58

1 Answers1

7

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

SOS
  • 6,430
  • 2
  • 11
  • 29
  • 2
    Wonderful and well explained answer! Deserves way more than one upvote! – AndreasRu May 12 '22 at 00:42
  • 1
    @SOS Thank you so much. You saved my time and energy and resolved the issue. Great explanation and Wonderful answer. I have applied your solution and It is working like a charm. Great!!! – dev May 12 '22 at 10:31