J'KYO
No pains,no gains.

 

 
    对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包使用方法,可以参阅官方文档:
 
 

Oracle中的MD5加密

一、技术点 
1、 DBMS_OBFUSCATION_TOOLKIT.MD5 
DBMS_OBFUSCATION_TOOLKIT.MD5是MD5编码的数据包函数,但偶在使用select DBMS_OBFUSCATION_TOOLKIT.MD5(input_string =>'abc') a from Dual时,却有错误提示,看来该函数只能直接在程序包中调用,不能直接应用于SELECT语句。 
  
2、Utl_Raw.Cast_To_Raw 
DBMS_OBFUSCATION_TOOLKIT.MD5返回的字串,是RAW类型,要正确显示,需要经过Utl_Raw.Cast_To_Raw转换

 

二、应用

1、直接调用

declare

v2 varchar2(32);

begin

v2 := Utl_Raw.Cast_To_Raw(sys.dbms_obfuscation_toolkit.md5(input_string => '111'));

dbms_output.put_line(v2);

end;

注意:可以在存储过程中直接调用,如果要嵌套调用md5时,记得每次调用后都用Utl_Raw.Cast_To_Raw进行转换,否则最后出来的结果是错误的。

 

2、构造函数后,再调用

CREATE OR REPLACE FUNCTION MD5(

passwd IN VARCHAR2)

RETURN VARCHAR2

IS

retval varchar2(32);

BEGIN

retval := utl_raw.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING => passwd)) ;

RETURN retval;

END;

 

调用md5函数示例:

select md5(1) from dual

相关链接:

http://blogt.chinaunix.net/space.php?uid=7848254&do=blog&id=2039418

http://www.anbob.com/?p=1326

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4447619263064

posted on 2017-06-22 17:08  J'KYO  阅读(3179)  评论(0编辑  收藏  举报