2014年5月21日 星期三

Oracle 資料加密功能 - dbms_crypto


Oracle 在10G 之前必須使用DBMS_OFUSCATION_TOOLKIT 來做加密與解密,10GR2之後提供了 DBMS_CRYPTO 功能上更為強大。


DBMS_CRYPTO 除了一般資料類型外也有支援RAW、LOBS、大數據類型 BLOB與CLOB (Oracle 稱聲音與圖像也可以)。


可以使用以下的加密技術
Data Encryption Standard (DES), Triple DES (3DES, 2-key and 3-key)
Advanced Encryption Standard (AES)
MD5, MD4, and SHA-1 cryptographic hashes
MD5 and SHA-1 Message Authentication Code (MAC)


DBMS_CRYPTO 加密算法
ENCRYPT_DES :數據加密標準。分組密碼。使用56位密鑰長度。
ENCRYPT_3DES_2KEY :數據加密標準。分組密碼。經營一個塊上3次,2把鑰匙。 112位有效密鑰長度。
ENCRYPT_3DES :數據加密標準。經營一個塊上3倍。
ENCRYPT_AES128 :高級標準加密。使用128位的密鑰大小。
ENCRYPT_AES192 :高級標準加密。使用192位的密鑰大小。
ENCRYPT_AES256 :高級標準加密。使用256位的密鑰大小。
ENCRYPT_RC4 :被用於加密數據流,隨機生成的密鑰是唯一的。

 DBMS_CRYPTO 填充方式
PAD_PKCS5 :提供填充它符合PKCS#5:基於密碼的加密標準
PAD_NONE :不去填充。必須確保長度大小是8字元,否則會出現錯誤。
PAD_ZERO :用零去填充。

DBMS_CRYPTO 連接方式
CHAIN_ECB :電子密碼本。獨立加密每個明文塊。
CHAIN_CBC :密碼塊鏈接。明文或與以前的密文塊之前被加密。
CHAIN_CFB :密碼反饋。啟用加密數據的單位的塊大小。
CHAIN_OFB :輸出反饋。允許運行一個分組密碼作為同步流密碼。類似於CFB,除了前面的輸出塊的是n位被移動到數據隊列的等待要被加密的最右邊的位置上。

注意
.1.DBMS_CRYPTO 包在 sys 底下,所以使用前還需授權給user
    SQL> grant execute on sys.dbms_crypto to Test ;

2.另外varchar2 必須轉換成RAW 才能輸入 DBMS_CRYPTO,可以使用UTL_RAW 或者 UTL_I18N 來做類型轉換

範例
1. 加密 - 使用的是 AES128 加密算法 + pkcs5 填充方式 + CBC 連結

code

 set serveroutput on
 declare
     input_data varchar2(20) := 'HELLO WORL'; --資料

     E_type pls_integer := dbms_crypto.encrypt_aes128 +
                           dbms_crypto.pad_pkcs5 +
                           dbms_crypto.chain_cbc;
     E_key varchar2(16) := '0123456789123456'; --鑰匙密碼

     E_encval raw(2000);
  begin
     E_encval := dbms_crypto.encrypt(
                    src=>utl_i18n.string_to_raw(input_data,'AL32UTF8'),
                    typ=>E_type,
                    key=>utl_i18n.string_to_raw(E_key,'AL32UTF8'));
     dbms_output.put_line(E_encval);
  end;
  /

putout
0637CFF59C55D05E8D22A82B6CC49CF8



2.解密

code

 set serveroutput on
 declare

     Encryption_data raw(100) := hextoraw('0637CFF59C55D05E8D22A82B6CC49CF8');

     E_type pls_integer := dbms_crypto.encrypt_aes128 +
                           dbms_crypto.pad_pkcs5 +
                           dbms_crypto.chain_cbc;

     E_key varchar2(16) := '0123456789123456'; --要與加密的鑰匙密碼一致
     E_Decryption raw(200);
  begin
     E_Decryption := dbms_crypto.decrypt(
                    src=>Encryption_data,
                    typ=>E_type,
                    key=>utl_i18n.string_to_raw(E_key,'AL32UTF8'));

     dbms_output.put_line(utl_i18n.raw_to_char(E_Decryption));
  end;
  /

putout
HELLO WORL






沒有留言:

張貼留言