Reputation: 495
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
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
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