Как передать точное значение varchar как raw в функцию dbms_crypto.mac
Я пытаюсь подключиться к веб-сервису и получить некоторую информацию. Веб-служба ожидает заголовок авторизации amx, и у меня возникли проблемы с его вычислением в Oracle 12c plsql. В документации API веб-сервиса приведен пример кода, который хорошо работает и написан на PHP. Когда я запускаю этот код PHP, я могу получить правильный заголовок аутентификации (возможность подключения к веб-сервису и получения данных).
Я пытаюсь вычислить эквивалент этого в plsql, и мне кажется, что отсутствует что-то базовое / сложное. Рассчитанная подпись отличается от подписи PHP. Я сравниваю значения, которые я получаю на каждом шаге в коде PHP, со значениями, которые я получаю в коде PLSQL.
Я хотел бы получить помощь в том, чтобы убедиться, что значения на каждом шаге в PHP соответствуют значениям в PLSQL.
Вот код PHP:
<?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("\n Data to encrypt is \n");
echo $data;
print_r("\n Key is \n");
echo $key;
print_r(" \n Secret \n");
echo $secret;
print_r("\n Signature \n");
echo $signature;
print_r("\n Return \n");
return 'amx ' . implode(':', [$id, $sign1, $nonce, $time]); //retorna a header
}
$header = amx_authorization_header('95618f328a5f29c3a182de24235e4d8e', 'MDAzCckCXqtDSTYL7QMP/UVmT4dtSpYmVyz9MH3ZrNU=', 'functionname', 'GET', '');
echo $header
?>
Выход из этого:
Data to Encrypt: 95618f328a5f29c3a182de24235e4d8eGEThttps%3a%2f%2fsomeurl.com%2fportfunctionname1557057252240c471b38a14891850876c5497f3013
Key: MDAzCckCXqtDSTYL7QMP/UVmT4dtSpYmVyz9MH3ZrNU=
Secret: 003 ^CI6EfOmJ&W,0}٬
Signature: XdEzgiJgen150sMDKTee5Zxq/pNZpKcOz3DFIT388UM=
Теперь вот код PLSQL, который я написал, пытаясь получить точно такой же результат, как и выше. Это в 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;
Вывод, который я имею из этого куска кода:
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=
Я получаю то же самое до "секрета". Однако, чтобы передать это в пакет dbms_crpyto, мне нужно привести это значение как RAW, а секретное значение RAW отличается. Может быть, это вызывает проблему? Если так, может кто-нибудь помочь исправить это?
Если нет, каковы другие возможные варианты?