user1779418
user1779418

Reputation: 495

dbms_crypto output mismatches with crypto-js

I'm working on creating an hmac-sha1 hash in Cerner's proprietary language, CCL. It's similar to PL/SQL and has access to native oracle functions. The idea is to mimic a hash created inside javascript. Oracle is using DBMS_CRYPTO and javascript is using CRYPTO.JS. Below are my two implementations, however I'm unable to get the hashes to match with basic testing strings.

If anyone can shed some light on what I'm doing wrong, I'd appreciate it! I've tried playing around with how I'm giving the data to the dbms_crypto.mac() function, but I'm not able to get it to match.

Javascript output: 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 output: 0BCC191B3A941C95ECAA46C8F825394706096E62

PL/SQL Sample that I'm trying to base my CCL on:

DECLARE
    typ       INTEGER := DBMS_CRYPTO.SH1;
    key       RAW(100) := 'testsecret';
    mac_value RAW(100);
BEGIN

mac_value := DBMS_CRYPTO.MAC('testconsumertestsecret', typ, key);

END;

Caveat - I'm not able to actually test the PL/SQL version, since I don't have an oracle sandbox to play in. I'm also not allowed to post the proprietary code on external websites, so I can't show my actual implementation.

Upvotes: 1

Views: 1291

Answers (2)

Abdullah Zabarah
Abdullah Zabarah

Reputation: 1

Once there is no compatibility between cryptoJS in JavaScript and dbms_crypto in Oracle PL/SQL, especially when encrypting using Pkcs7, The following code shows how that can be done. The answer is here:

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

Upvotes: 0

user1779418
user1779418

Reputation: 495

I was using an incorrect or outdated example.

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

Upvotes: 1

Related Questions