Как передать точное значение 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 отличается. Может быть, это вызывает проблему? Если так, может кто-нибудь помочь исправить это?

Если нет, каковы другие возможные варианты?

0 ответов

Другие вопросы по тегам