Decode360's Blog

          業精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
          DBMS_CRYPTO包對Oracle加密
          ?
          ?
          ??? 對Oracle內部數據的加密,可以簡單得使用DBMS_CRYPTO來進行,效果還是不錯的,而且使用也比較方便,所以今天專門來學習一下這個包的使用方法。在使用之前,要注意兩件事情:
          ?
          ??? 1、DBMS_CRYPTO包是10g才有的,如果在10g以前的版本,使用DBMS_OBFUSCATION_TOOLKIT包;
          ??? 2、DBMS_CRYPTO默認只有SYSDBA用戶才可執行,所以其他的任何用戶都需要SYSDBA進行賦權。
          ?
          ?
          一、簡單的隨機值生成
          ?
          ??? 使用DBMS_CRYPTO包可以有3個函數來生成簡單的隨機值,包括3種——數字、整數、字符。使用這些隨機數生成函數是為了在加密是生成隨機的密匙。這幾個函數的使用很簡單,看一下具體例子就可以馬上明白:

          SQL> select DBMS_CRYPTO.RandomInteger from dual;--生成整數(有正有負)
          ?
          RANDOMINTEGER
          -------------
          ?? -284171810

          SQL> select DBMS_CRYPTO.RandomBytes(6) from dual;--生成6位Bytes(注意返回的不是byte是raw)
          ?
          DBMS_CRYPTO.RANDOMBYTES(6)
          ------------------------------
          FFEE2CB53DB4

          SQL> select DBMS_CRYPTO.RandomNumber from dual;--生成Number(正數)
          ?
          RANDOMNUMBER
          ------------
          6.6453693840
          ?
          ?
          二、簡單的示例
          ?
          ??? 首先看一下用于生成加密的函數(暫時不考慮BLOB類型的加密):
          ?
          ??? FUNCTION? Encrypt (src IN??????????? RAW,
          ?????????????????????? typ IN??????????? PLS_INTEGER,
          ?????????????????????? key IN??????????? RAW,
          ?????????????????????? iv? IN??????????? RAW????????? DEFAULT NULL)
          ????? RETURN RAW;
          ?
          ??? 解釋一下:
          ?
          ??? 1、src:需要加密的內容,但是需要轉換為RAW格式,不能直接對VARCHAR2格式加密
          ??? 2、typ:加密類型,由DBMS_CRYPTO定義,可以查詢DBMS_CRYPTO包中的Declare部分
          ??? 3、key:即加密的密匙,如需解密則需要知道原先的密匙
          ??? 4、iv:block密碼的選項,一般都置為默認,默認為null
          ?
          ??? 下面簡單舉例說明:
          ?
          SQL> DECLARE
          ? 2??? input_string???? VARCHAR2(30) := '需要加密的內容';
          ? 3??? raw_input??????? RAW(128) := UTL_RAW.CAST_TO_RAW(input_string);
          ? 4??? --將需要加密的內容轉換成RAW格式
          ? 5??? raw_key????????? RAW(256);
          ? 6??? encrypted_raw??? RAW(2048);
          ? 7??? encrypted_string VARCHAR2(2048);
          ? 8??? decrypted_raw??? RAW(2048);
          ? 9??? decrypted_string VARCHAR2(2048);
          10?
          11? BEGIN
          12??? dbms_output.put_line('> ========= Get Key Bytes =========');
          13?
          14??? raw_key := dbms_crypto.randombytes(24);
          15??? --隨機生成的48位字符密匙
          16??? dbms_output.put_line('> Key String length: ' || UTL_RAW.LENGTH(raw_key));
          17??? dbms_output.put_line('> Key String: ' || UTL_RAW.CAST_TO_VARCHAR2(raw_key));
          18??? dbms_output.put_line('> Input String: ' || input_string);
          19??? dbms_output.put_line('> ========= BEGIN TEST Encrypt =========');
          20??? --加密
          21??? encrypted_raw := dbms_crypto.Encrypt(src => raw_input,
          22???????????????????????????????????????? typ => DBMS_CRYPTO.DES3_CBC_PKCS5,
          23???????????????????????????????????????? key => raw_key);
          24?
          25??? dbms_output.put_line('> Encrypted hex value : ' || rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
          26??? dbms_output.put_line('> Encrypted varchar2 value: ' || UTL_RAW.CAST_TO_VARCHAR2(encrypted_raw));
          27??? --解密
          28??? decrypted_raw := dbms_crypto.Decrypt(src => encrypted_raw,
          29???????????????????????????????????????? typ => DBMS_CRYPTO.DES3_CBC_PKCS5,
          30???????????????????????????????????????? key => raw_key);
          31??? --將解密后的RAW轉換成String
          32??? decrypted_string := UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw);
          33?
          34??? dbms_output.put_line('> Decrypted string output : ' || decrypted_string);
          35?
          36??? if input_string = decrypted_string THEN
          37????? dbms_output.put_line('> String DES Encyption and Decryption successful');
          38??? END if;
          39? END;
          40? /
          ?
          > ========= Get Key Bytes =========
          > Key String length: 24
          > Key String: 峈報T??崛╭顋賣I~漥?篻
          > Input String: 需要加密的內容
          > ========= BEGIN TEST Encrypt =========
          > Encrypted hex value : 374132424133453633303945433530364534414334443943303346343735303643464630393330313436454441443930
          > Encrypted varchar2 value: z+f0炁洮M?魎橡?F憝
          ???????????
          ?
          ??? 說明:
          ?
          ??? 1、可以看到,用dbms_crypto.randombytes(24)生成的是24位的亂碼
          ??? 2、解密時必須提供加密時的Key,所以在使用加密時可以使用固定的復雜字符串。
          ?
          ?
          三、我設的加密/解密函數
          ?
          SQL>
          SQL> --加密函數
          SQL> create or replace function t_to_password(string_in in varchar2) return raw is
          ? 2??? string_in_raw RAW(128) := UTL_RAW.CAST_TO_RAW(string_in);
          ? 3??? key_string varchar2(32) := 'WANGXIAOQI._ROW@KEY-PASSWORD8888';
          ? 4??? key_raw RAW(128) := UTL_RAW.CAST_TO_RAW(key_string);
          ? 5??? encrypted_raw RAW(128);
          ? 6? begin
          ? 7??? encrypted_raw := dbms_crypto.Encrypt(src => string_in_raw,
          ? 8???????????????????????????????????????? typ => DBMS_CRYPTO.DES3_CBC_PKCS5,
          ? 9???????????????????????????????????????? key => key_raw);
          10??? return encrypted_raw;
          11? end;
          12? /
          ?
          Function created
          ?
          SQL>
          SQL> --解密函數
          SQL> create or replace function t_to_back(raw_in in raw) return varchar2 is
          ? 2??? string_out varchar2(50);
          ? 3??? key_string varchar2(32) := 'WANGXIAOQImailto:'SINATAY.COM_ROW@KEY-PASSWORD8888';
          ? 4??? key_raw RAW(128) := UTL_RAW.CAST_TO_RAW(key_string);
          ? 5??? decrypted_raw RAW(128);
          ? 6? begin
          ? 7??? decrypted_raw := dbms_crypto.Decrypt(src => raw_in,
          ? 8???????????????????????????????????????? typ => DBMS_CRYPTO.DES3_CBC_PKCS5,
          ? 9???????????????????????????????????????? key => key_raw);
          10??? string_out := UTL_RAW.cast_to_varchar2(decrypted_raw);
          11??? return string_out;
          12? end;
          13? /
          ?
          Function created
          ?
          SQL>
          SQL> create table t_name(a int primary key,
          ? 2????????????????????? psw varchar2(100));
          ?
          Table created
          ?
          SQL>
          SQL> insert into t_name values(1, t_to_password('password'));
          ?
          1 row inserted
          SQL> insert into t_name values(2, t_to_password('ilovebaby'));
          ?
          1 row inserted
          SQL> insert into t_name values(3, t_to_password('@1123'));
          ?
          1 row inserted
          ?
          SQL> select * from t_name;
          ?
          ????????????????????????????????????? A PSW
          --------------------------------------- --------------------------------------------------------------------------------
          ????????????????????????????????????? 1 A8C933B456FEDE0E99D7A55CC99758E6
          ????????????????????????????????????? 2 D8DDDA409E4AB8E19144C0762027ACCB
          ????????????????????????????????????? 3 D7116CC53A09F98F
          ?
          SQL> select a,t_to_back(psw) psw from t_name;
          ?
          ????????????????????????????????????? A PSW
          --------------------------------------- --------------------------------------------------------------------------------
          ????????????????????????????????????? 1 password
          ????????????????????????????????????? 2 ilovebaby
          ????????????????????????????????????? 3 @1123
          ?
          SQL>
          ?
          ?
          ??? OK,測試成功。
          ?
          ?
          ??? 如果需要了解詳細的DBMS_CRYPTO包使用方法,可以參閱官方文檔:
          ??? http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_crypto.htm
          ?
          posted on 2009-08-30 21:27 decode360 閱讀(2876) 評論(0)  編輯  收藏 所屬分類: 06.PLSQL
          主站蜘蛛池模板: 游戏| 汉寿县| 连云港市| 沅陵县| 彰武县| 清新县| 绥棱县| 上林县| 临泽县| 长治县| 商河县| 柳江县| 济南市| 吉安市| 河南省| 通城县| 正宁县| 建始县| 香格里拉县| 青浦区| 定日县| 阆中市| 鹤壁市| 芷江| 定南县| 西城区| 普宁市| 南康市| 阜康市| 丁青县| 藁城市| 肇庆市| 托克逊县| 宜宾市| 凌源市| 浦城县| 孝昌县| 林州市| 柘城县| 大余县| 潍坊市|