I am trying to connect to a webservice and retrieve some information. The webservice expects an amx authorization header and I have problem computing it within Oracle 12c plsql. There is a sample code given on the webservice API documentation that works well and it is written in PHP. When I run this PHP code, I am able to get the right authentication header (able to connect to webservice and fetch data).
I am trying to compute the equivalent of it in plsql and I seem to be missing something basic/complex. The signature computed is different than that of PHP. I am comparing the values I receive at each step within the PHP code with the values I receive in the PLSQL code.
I would like to receive help in making sure that the values at each step in PHP match the values in PLSQL.
Here is the PHP Code:
<?php
function amx_authorization_header($id, $key, $function, $method, $body) {
$url1 = 'https://someurl.com/port/' . $function;
$url = strtolower(urlencode($url1));
$content = empty($body) ? '' : base64_encode(md5($body, true));
#$time = time(); //Tempo
$time = '1557057252';
#$nonce = uniqid();
$nonce = '240c471b38a14891850876c5497f3013';
$data = implode('', [$id, strtoupper($method), $url, $time, $nonce, $content]);
$secret = base64_decode($key);
$signature = base64_encode(hash_hmac('sha256', $data, $secret, true));
print_r("
Data to encrypt is
");
echo $data;
print_r("
Key is
");
echo $key;
print_r("
Secret
");
echo $secret;
print_r("
Signature
");
echo $signature;
print_r("
Return
");
return 'amx ' . implode(':', [$id, $sign1, $nonce, $time]); //retorna a header
}
$header = amx_authorization_header('95618f328a5f29c3a182de24235e4d8e', 'MDAzCckCXqtDSTYL7QMP/UVmT4dtSpYmVyz9MH3ZrNU=', 'functionname', 'GET', '');
echo $header
?>
The output from this is :
Data to Encrypt: 95618f328a5f29c3a182de24235e4d8eGEThttps%3a%2f%2fsomeurl.com%2fportfunctionname1557057252240c471b38a14891850876c5497f3013
Key: MDAzCckCXqtDSTYL7QMP/UVmT4dtSpYmVyz9MH3ZrNU=
Secret: 003 ^CI6EfOmJ&W,0}٬
Signature: XdEzgiJgen150sMDKTee5Zxq/pNZpKcOz3DFIT388UM=
Now, here is the PLSQL code I wrote trying to achieve exactly the same output as above. This is in Oracle 12c.
DECLARE
p_auth_id VARCHAR2(50) := '95618f328a5f29c3a182de24235e4d8e';
p_auth_key VARCHAR2(50) := 'MDAzCckCXqtDSTYL7QMP/UVmT4dtSpYmVyz9MH3ZrNU=';
p_web_url VARCHAR2(100):= 'https://someurl.com/port/functionname';
p_rqst_mthd VARCHAR2(10) := 'GET';
v_encoded_url VARCHAR2(400);
n_timestamp NUMBER;
v_uuid VARCHAR2(40);
v_data VARCHAR2(1000);
v_secret VARCHAR2(100);
v_signature VARCHAR2(200);
v_raw RAW(50);
BEGIN
v_encoded_url := lower(utl_url.escape(url => p_web_url, escape_reserved_chars => TRUE));
n_timestamp := 1557057252;
v_uuid := '240c471b38a14891850876c5497f3013';
v_data := p_auth_id || p_rqst_mthd || v_encoded_url || n_timestamp || v_uuid;
v_secret := lower(utl_raw.cast_to_varchar2(utl_encode.base64_decode(utl_raw.cast_to_raw(p_auth_key))));
dbms_output.put_line('Data to Encrypt: ' || v_data);
dbms_output.put_line('Key: ' || p_auth_key);
dbms_output.put_line('Secret: ' || v_secret);
v_raw := utl_raw.cast_to_raw(v_secret);
dbms_output.put_line('Raw secret: ' || v_raw);
v_signature := lower(DBMS_CRYPTO.MAC(src => utl_raw.cast_to_raw(v_data), typ => DBMS_CRYPTO.HMAC_SH256, key => (utl_raw.cast_to_raw(v_secret))));
v_signature := utl_raw.cast_to_varchar2(utl_encode.base64_encode(v_signature));
dbms_output.put_line('Signature: ' || v_signature);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Error here ' || SQLERRM);
END;
The output I have from this piece of code is :
Data to Encrypt: 95618f328a5f29c3a182de24235e4d8eGEThttps%3a%2f%2fsomeurl.com%2fport%2ffunctionname1557057252240c471b38a14891850876c5497f3013
Key: MDAzCckCXqtDSTYL7QMP/UVmT4dtSpYmVyz9MH3ZrNU=
Secret: 003 �^�ci6��efo�mj�&w,�0}٬
Raw secret: 30303309C9025EAB6369360BED030FFD65666F876D6A9626772CFD307DD9AC
Signature: tEtzY9WCk9+lG+kf7YpYfloXtFe51LAKstQFHhy4uxM=
I get the same until “secret”. However, to pass this to dbms_crpyto package, I need to cast this as RAW and the RAW secret value is different. Maybe this is causing the issue? If so, can anyone help fix this?
If not, what are the other possible options?