Oracle加密解密

Oracle內部有專門的加密包,能夠很方便的對內部數據進行加密(encrypt)和解密(decrypt).算法

  介紹加密包以前,先簡單說一下Oracle基本數據類型——RAW類型sql

  RAW,用於保存位串的數據類型,相似於CHAR,聲明方式RAW(L),L爲長度,以字節爲單位,做爲數據庫列最大2000,做爲變量最大32767字節。數據庫

     操做RAW類型的函數:安全

    utl_raw.cast_to_raw([varchar2]):將varchar2轉換爲raw類型oracle

    utl_raw.cast_to_varchar2([raw]):將raw轉換爲varchar2類型dom

    hextoraw():十六進制字符串轉換爲raw函數

    rawtohex():將raw串轉換爲十六進制工具

      注:RAW保存的爲16進制數,當使用HEXTORAW時,會把字符串中數據看成16進制數。而使用UTL_RAW.CAST_TO_RAW時,直接把字符串中每一個字符的ASCII碼存放到RAW類型的字段中。測試

           eg>select hextoraw('abc') from dual;    --輸出結果爲: ABC加密

    eg>select utl_raw.cast_to_raw('abc') from dual;    --輸出結果爲: 616263(a的ASCII碼值爲97,轉換成16進制數爲61)

 

下面介紹一下Oracle中的加密包:

1,Dbms_Obfuscation_Toolkit(9i)

  利用Dbms_Obfuscation_Toolkit包,咱們能夠對數據進行DES,Triple DES或者MD5加密

     DESGETKEY   -- 產生密鑰,用於DES算法
     DES3GETKEY  -- 產生密鑰,用於Triple DES算法
     DESENCRYPT  -- 用DES算法加密數據
     DESDECRYPT  -- 用DES算法解密數據
     DES3ENCRYPT -- 用Triple DES算法加密數據
     DES3DECRYPT -- 用DES算法解密數據
     MD5         -- 用MD5算法加密數據

  加密包中分別採用raw和string兩種數據類型加密,分別測試一下:(注:加密的字符串(input_string)必須是8的倍數)

DES算法加密解密

DECLARE
  v_input VARCHAR2(100) := '12345678';
  v_key   VARCHAR2(100) := 'oracle9i';
  -- ORA-28232: obfuscation 工具箱的輸入長度無效(緣由是加密字符串必須是8的倍數)

  encrypted_str VARCHAR2(4000);
  decrypted_str VARCHAR2(4000);
  encrypted_raw RAW(4000);
  decrypted_raw RAW(4000);
BEGIN
  -- string類型加密解密
  -- encrypt(string)
  dbms_obfuscation_toolkit.desencrypt(input_string => v_input, key_string => v_key, encrypted_string => encrypted_str);
  dbms_output.put_line('Encrypted string: ' || encrypted_str);
  dbms_output.put_line('Encrypted hex value: ' || utl_raw.cast_to_raw(encrypted_str));
  -- decrypt(string)
  dbms_obfuscation_toolkit.desdecrypt(input_string => encrypted_str, key_string => v_key, decrypted_string => decrypted_str);
  dbms_output.put_line('Decrypted String: ' || decrypted_str);

  -- raw類型加密解密
  -- encrypt(raw)
  dbms_obfuscation_toolkit.desencrypt(input => utl_raw.cast_to_raw(v_input), key => utl_raw.cast_to_raw(v_key), encrypted_data => encrypted_raw);
  dbms_output.put_line('Encrypted Raw: ' || encrypted_raw);
  dbms_output.put_line('Encrypted hex value: ' || rawtohex(encrypted_raw));
  -- decrypt(raw)
  dbms_obfuscation_toolkit.desdecrypt(input => encrypted_raw, key => utl_raw.cast_to_raw(v_key), decrypted_data => decrypted_raw);
  dbms_output.put_line('Decrypted String: ' || utl_raw.cast_to_varchar2(decrypted_raw));
END;

注:DES算法加密的key長度必須大於等於8,並且加密的結果只跟其前8位有關(推測多是截取了字符串);

Triple DES算法加密(DES3ENCRYPT)用法同DES基本相似,安全性叫DES算法更高;

    同理,Triple DES算法的key長度必須大於等於16,且結果只與其前16位有關;

 (Extra:數據類型PLS_INTEGER能夠存儲一個有符號的整型值,其精度範圍和BINARY_INTEGER同樣,是-2^31~2^31

MD5算法加密

DECLARE
  v_str VARCHAR2(100) := '123456';
  v_key VARCHAR2(100) := 'oracle9i';
  
  encrypted_str VARCHAR2(32);
  encrypted_raw RAW(32);
BEGIN
  -- encrypted as string
  dbms_obfuscation_toolkit.MD5(input_string => v_str || v_key, checksum_string => encrypted_str);
  dbms_output.put_line('Encrypted String: ' || encrypted_str);
  dbms_output.put_line('Encrypted hex value: ' || utl_raw.cast_to_raw(encrypted_str));
  
  -- encrypted as raw
  dbms_obfuscation_toolkit.MD5(input => utl_raw.cast_to_raw(v_str || v_key), checksum => encrypted_raw);
  dbms_output.put_line('Encrypted Raw: ' || encrypted_raw);
  dbms_output.put_line('Encrypted hex value: ' || rawtohex(encrypted_raw));
END;

 注:MD5算法只能正向加密,但它屢次對於同一數據的加密計算結果是相同的。

 

2,dbms_crypto(10g之後)

  dbms_crypto包默認只有sysdba用戶纔可執行,其餘任何用戶都須要sysdba進行受權

  sys>grant execute on dbms_crypto to scott;

-- 示例(不考慮BLOB類型的加密)
DECLARE v_str VARCHAR2(20) := '12345678'; -- 加密的字符串 v_type PLS_INTEGER := dbms_crypto.DES_CBC_PKCS5; -- 加密類型 v_key RAW(256); v_key1 VARCHAR2(100) := 'oracle9i012'; encrypted_raw RAW(256); decrypted_raw RAW(256); BEGIN -- 生成隨機16位密鑰 (1個byte等於兩位raw) v_key := dbms_crypto.RandomBytes(8); dbms_output.put_line('Encrypted Key: ' || v_key); -- 加密 encrypted_raw := dbms_crypto.Encrypt(src => utl_raw.cast_to_raw(v_str), typ => v_type, key => v_key); dbms_output.put_line('Encrypted Raw: ' || encrypted_raw); dbms_output.put_line('Encrypted hex value: ' || rawtohex(encrypted_raw)); -- 解密 decrypted_raw := dbms_crypto.Decrypt(src => encrypted_raw, typ => v_type, key => v_key); dbms_output.put_line('Decrypted String: ' || utl_raw.cast_to_varchar2(decrypted_raw)); END;

 能夠加加密和解密的內容寫入函數中,方便使用的時候直接調用。

相關文章
相關標籤/搜索