PDA

View Full Version : problem tuse hmac with library



franco
30-Jun-2022, 06:41 AM
hello
I have a problem I think with Hmac function using latest 1.1 version dataflex security library and DF 20.1, I need to recreate a signature and then compare with original one that need to test if a call back POST message I receveing come from a known source
I testing using original sample in PHP that work and reproducing it in DF the check of signature. Below my df test signature and HMAC function I using which result is

0f15494ad25ef7fef044bf0c668814ba168d76788f8cf34376 b0eec4d84bd08d

while should be 8ef2a0f0c6826895593d0d137cf6ce7353a4bbe999d4a6c363 f92f1e9d7f8e32 . I'm not sure if can depend by HMAC used not correctly by me I can note that it return uchar 32 elements array while parameter UChar[] ucaData UChar[] ucaKey are both 64elements maybe it is normal Maybe need to use some alg different CALG_SHA_256 but it should be correct)



Function HMAC Global UChar[] ucaData UChar[] ucaKey Returns UChar[]
Boolean bOK
UChar[] ucaHMAC
Handle hoHMAC
Integer iAlg


Move CALG_SHA_256 to iAlg


Get Create (RefClass(cSecureHash)) to hoHMAC
If (iAlg = CALG_SHA_256) ;
Set piHashImplementation of hoHMAC to C_SEC_HASH_CNG_HMAC_SHA256

Send Initialize of hoHMAC (&ucaKey)
Send Update of hoHMAC ucaData
Get Finalize of hoHMAC to ucaHMAC
Send Destroy of hoHMAC

Function_Return ucaHMAC
End_Function

Function testsignature String ssignature String smessage Returns Boolean
String sSigntocheckex
UChar[] hash_secret ucaKey ucaData uchash_hmac_result


String hash_secret

Get StringToSHA256Hash of oDataCrypter (String('E8kOq803ktB7')+ (String('E8kOq803ktB7'))) to hash_secret

Move ("20.00010000122021-09-30T13:02:34.059939+00:00") to smessage // same that in Php code

Move (StringToUCharArray(hash_secret)) to ucaKey
Move (StringToUCharArray(smessage)) to ucaData

Get HMAC ucaData ucaKey to uchash_hmac_result

Get Bin2Hex of ghoSecurity uchash_hmac_result to sSigntocheckex


Function_Return (sSigntocheckex = ssignature)
End_Procedure

get testsignature "8ef2a0f0c6826895593d0d137cf6ce7353a4bbe999d4a6c363 f92f1e9d7f8e32" ("20.00010000122021-09-30T13:02:34.059939+00:00") to WindowIndex



follow original test sample that return "verified" same message and login/pasw I used on DF

<?php


# set API user login and password
$login = 'E8kOq803ktB7';
$password = 'E8kOq803ktB7';


# parse callback data
$callback_payload = json_decode(
'
{
"data": {
"type": "payout",
"id": "26",
"attributes": {
"address": "2NBr9k5xhvE2PxAAiFuczqQkeN76ShMdRZ6",
"created_at": "2021-09-30T13:01:49.930612Z",
"tracking_id": "12",
"fee_amount": "0.00000823",
"is_fee_included": false,
"amount": "0.00010000",
"destination": {
"address_type": "legacy",
"address": "2NBr9k5xhvE2PxAAiFuczqQkeN76ShMdRZ6"
}
},
"relationships": {
"wallet": {
"data": {
"type": "wallet",
"id": "19"
}
},
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
},
"transfer": {
"data": {
"type": "transfer",
"id": "145"
}
}
}
},
"included": [
{
"type": "currency",
"id": "1000",
"attributes": {
"iso": 1000,
"name": "Bitcoin",
"alpha": "BTC",
"alias": null,
"exp": 8,
"confirmation_blocks": 3,
"minimal_transfer_amount": "0.00000546",
"block_delay": 3600
}
},
{
"type": "transfer",
"id": "145",
"attributes": {
"confirmations": 3,
"risk": 0,
"risk_status": 4,
"op_id": 26,
"op_type": 2,
"amount": "0.00010000",
"commission": "0.00000000",
"fee": "0.00000823",
"txid": "c3cc36f4569fdbfaacdbc14647e5046d9f239ab1af0268b531 a5a213411a8fc9",
"status": 2,
"message": null,
"user_message": null,
"created_at": "2021-09-30T13:01:50.273446Z",
"updated_at": "2021-09-30T13:02:33.743770Z"
},
"relationships": {
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
}
}
}
],
"meta": {
"time": "2021-09-30T13:02:34.059939+00:00",
"sign": "8ef2a0f0c6826895593d0d137cf6ce7353a4bbe999d4a6c363 f92f1e9d7f8e32"
}
}
',
true
);


$callback_sign = $callback_payload['meta']['sign'];
$callback_time = $callback_payload['meta']['time'];


# retrieve transfer and deposit attributes
$included_transfer = array_filter(
$callback_payload['included'],
function ($item) {
return $item['type'] === 'transfer';
}
);
$included_transfer = array_pop($included_transfer)['attributes'];
$deposit = $callback_payload['data']['attributes'];


$status = $included_transfer['status'];
$amount = $included_transfer['amount'];
$tracking_id = $deposit['tracking_id'];


# prepare data for hash check
# $message = $status . $amount . $tracking_id . $callback_time;
$message = "20.00010000122021-09-30T13:02:34.059939+00:00";
$hash_secret = hash('sha256', $login . $password, true);
$hash_hmac_result = hash_hmac('sha256', $message, $hash_secret);


# print result
if ($hash_hmac_result === $callback_sign) {

echo 'Verified';
} else {
echo 'Invalid sign';
}
echo PHP_EOL;

franco
30-Jun-2022, 08:22 AM
I found the solution was simple if can be useful I post here. it Was need to convert HEX to bin the sha256has string and pass it to HMAC instead that in HEX format

This is my coirrect testsignature


Function testsignature String ssignature String smessage Returns Boolean
String sSigntocheckex shash_hmac_result sSigntocheck
UChar[] hchash_secret uchash_hmac_result
UChar[] ucaData ucaKey hash_secretbin
Handle hoHMAC
String hash_secret
Get StringToSHA256Hash of oDataCrypter (String(C_B2BKEY)+ (String(C_B2BSECRET))) to hash_secret

Get Hex2Bin of ghoSecurity hash_secret to ucaKey

Move (StringToUCharArray(smessage)) to ucaData

Get HMAC ucaData ucaKey to uchash_hmac_result

Get Bin2Hex of ghoSecurity uchash_hmac_result to sSigntocheckex


Function_Return (sSigntocheckex = ssignature)
End_Procedure