Oracle內部有專門的加密包,可以很方便的對內部數據進行加密(encrypt)和解密(decrypt).
介紹加密包之前,先簡單說一下Oracle基本數據類型——RAW類型。
RAW,用于保存位串的數據類型,類似于CHAR,聲明方式RAW(L),L為長度,以字節為單位,作為數據庫列最大2000,作為變量最大32767字節。
? ?? 操作RAW類型的函數:
utl_raw.cast_to_raw([varchar2]):將varchar2轉換為raw類型
utl_raw.cast_to_varchar2([raw]):將raw轉換為varchar2類型
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算法加密解密
DECLAREv_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算法加密
DECLAREv_str VARCHAR2(100) := '123456';v_key VARCHAR2(100) := 'oracle9i';encrypted_str VARCHAR2(32);encrypted_raw RAW(32);
BEGIN-- encrypted as stringdbms_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 rawdbms_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類型的加密)
DECLAREv_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;
?可以加加密和解密的內容寫入函數中,方便使用的時候直接調用。