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