Вывод dbms_crypto не совпадает с crypto-js
Я работаю над созданием хэша hmac-sha1 на проприетарном языке Cerner, CCL. Он похож на PL/SQL и имеет доступ к собственным функциям оракула. Идея состоит в том, чтобы имитировать хеш, созданный внутри javascript. Oracle использует DBMS_CRYPTO, а javascript использует CRYPTO.JS. Ниже приведены две мои реализации, однако я не могу заставить хеши соответствовать базовым строкам тестирования.
Если кто-то может пролить свет на то, что я делаю неправильно, я был бы признателен! Я пытался поиграть с тем, как я передаю данные в функцию dbms_crypto.mac(), но я не могу заставить их соответствовать.
Вывод JavaScript: bad02f0a5324ad708bb8100220bae499e2c127b8
Codepen: https://codepen.io/bookluvr416/pen/jzmVWx
var consumerKey = "testConsumer";
var secretKey = "testSecret";
var valueToSign = consumerKey + secretKey;
var hmac = Crypto.HMAC(Crypto.SHA1, valueToSign.toLowerCase(),
secretKey.toLowerCase(), { asBytes: false });
Выход DBMS_CRYPTO: 0BCC191B3A941C95ECAA46C8F825394706096E62
Пример PL/SQL, на котором я пытаюсь основать свой CCL:
DECLARE
typ INTEGER := DBMS_CRYPTO.SH1;
key RAW(100) := 'testsecret';
mac_value RAW(100);
BEGIN
mac_value := DBMS_CRYPTO.MAC('testconsumertestsecret', typ, key);
END;
Предостережение - я не могу на самом деле протестировать версию PL/SQL, так как у меня нет песочницы для оракула для игры. Мне также не разрешается публиковать проприетарный код на внешних сайтах, поэтому я не могу показать моя фактическая реализация.
1 ответ
Я использовал неправильный или устаревший пример.
DBMS_CRYPTO.mac(UTL_I18N.string_to_raw(l_oauth_base_string, 'AL32UTF8')
,DBMS_CRYPTO.hmac_sh1
,UTL_I18N.string_to_raw(l_oauth_key, 'AL32UTF8'));
Если нет совместимости между cryptoJS в JavaScript и dbms_crypto в Oracle PL/SQL, особенно при шифровании с использованием Pkcs7, следующий код показывает, как это можно сделать. Ответ здесь:
Javascript
var AesUtil = function() {};
AesUtil.prototype.encrypt = function(key, iv, plainText) {
var encrypted = CryptoJS.AES.encrypt(
plainText,
CryptoJS.enc.Base64.parse(key),
{ iv: CryptoJS.enc.Utf8.parse(iv), mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}
AesUtil.prototype.decrypt = function(key, iv, cipherText) {
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(cipherText)
});
var decrypted = CryptoJS.AES.decrypt(
cipherParams,
CryptoJS.enc.Base64.parse(key),
{ iv: CryptoJS.enc.Utf8.parse(iv), mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
return decrypted.toString(CryptoJS.enc.Utf8);
}
PL/SQL
create or replace package encrypt_decrypt_pk as
-- Created by Abdullah Zabarah 19/09/2020
-- grant execute on sys.dbms_crypto to <Your Schema>; -- Using sysdba
function fn_encrypt(a_text in varchar2, a_key varchar2, a_iv varchar2) return varchar2;
function fn_decrypt(a_token in varchar2, a_key varchar2, a_iv varchar2) return varchar2;
end encrypt_decrypt_pk;
/
create or replace package body encrypt_decrypt_pk as
-- Created by Abdullah Zabarah 19/09/2020
-- grant execute on sys.dbms_crypto to <Your Schema>; -- Using sysdba
function fn_encrypt(a_text in varchar2, a_key varchar2, a_iv varchar2)
return varchar2
as
encryption_type pls_integer :=
dbms_crypto.encrypt_aes128
+ dbms_crypto.chain_cbc
+ dbms_crypto.pad_pkcs5;
begin
return utl_raw.cast_to_varchar2(utl_encode.base64_encode(dbms_crypto.encrypt(
src => utl_raw.cast_to_raw(a_text),
typ => encryption_type,
key => utl_encode.base64_decode(utl_raw.cast_to_raw(a_key)),
iv => utl_raw.cast_to_raw(a_iv)
)));
end;
function fn_decrypt(a_token in varchar2, a_key varchar2, a_iv varchar2)
return varchar2
as
encryption_type pls_integer :=
dbms_crypto.encrypt_aes128
+ dbms_crypto.chain_cbc
+ dbms_crypto.pad_pkcs5;
begin
return utl_raw.cast_to_varchar2(dbms_crypto.decrypt(
src => utl_encode.base64_decode(utl_raw.cast_to_raw(a_token)),
typ => encryption_type,
key => utl_encode.base64_decode(utl_raw.cast_to_raw(a_key)),
iv => utl_raw.cast_to_raw(a_iv)
));
end;
end encrypt_decrypt_pk;
/