Oracle中的加解密函数

对Oracle内部数据的加密,可以简单得使用DBMS_CRYPTO来进行,效果还是不错的,而且使用也比较方便,所以今天专门来学习一下这个包的使用方法。在使用之前,要注意两件事情:
1、DBMS_CRYPTO包是10g才有的,如果在10g以前的版本,使用DBMS_OBFUSCATION_TOOLKIT包;
2、DBMS_CRYPTO默认只有SYSDBA用户才可执行,所以其他的任何用户都需要SYSDBA进行赋权。
      grant execute on dbms_crypto to user;

如果想详细了解DBMS_CRYPTO包的使用,可以查阅官方文档: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_crypto.htm

一、随机值生成

使用DBMS_CRYPTO包可以有3个函数(RandomIntegerRandomBytesRandomNumber)来生成简单的随机值。使用这些随机数生成函数是为了在加密时生成随机的密钥。

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

二、加解密函数

1、加密函数encrypt

FUNCTION Encrypt (src IN RAW,
                  typ IN PLS_INTEGER,
                  key IN RAW,
                  iv  IN RAW DEFAULT NULL)
    RETURN RAW;
    解释一下:
    1、src:需要加密的内容,但是需要转换为RAW格式,不能直接对VARCHAR2格式加密.使用UTL_RAW.CAST_TO_RAWUTL_I18N.STRING_TO_RAW函数将varchar2类型转换为raw类型
    2、typ:加密类型,由DBMS_CRYPTO定义,可以查询DBMS_CRYPTO包中的Declare部分
    3、key:即加密的密钥,如需解密则需要知道原先的密钥
    4、iv:block密码的选项,一般都置为默认,默认为null

2、解密函数decrypt

FUNCTION DECRYPT(src IN RAW,
                 typ IN PLS_INTEGER,
                 key IN RAW,
                 iv  IN RAW  DEFAULT NULL)
    RETURN RAW;
    解释一下:
    1、src:需要解密的内容。解密之后为RAW格式,使用UTL_RAW.CAST_TO_VARCHAR2UTL_I18N.RAW_TO_CHAR函数将raw类型转换为varchar2类型
    2、typ:加密类型,由DBMS_CRYPTO定义,可以查询DBMS_CRYPTO包中的Declare部分
    3、key:即加密的密钥,如需解密则需要知道原先的密钥
    4、iv:block密码的选项,一般都置为默认,默认为null

3、加密类型

 

三、示例

DECLARE
   input_string     VARCHAR2(30) := '需要加密的内容';
   raw_input        RAW(128) := UTL_RAW.CAST_TO_RAW(input_string);
   --将需要加密的内容转换成RAW格式
   raw_key          RAW(256);
   encrypted_raw    RAW(2048);
   encrypted_string VARCHAR2(2048);
   decrypted_raw    RAW(2048);
   decrypted_string VARCHAR2(2048);
  
BEGIN
    dbms_output.put_line('> ========= Get Key Bytes =========');

    raw_key := dbms_crypto.randombytes(24);
    --随机生成的48位字符密匙
    dbms_output.put_line('> Key String length: ' || UTL_RAW.LENGTH(raw_key));
    dbms_output.put_line('> Key String: ' || UTL_RAW.CAST_TO_VARCHAR2(raw_key));
    dbms_output.put_line('> Input String: ' || input_string);
    dbms_output.put_line('> ========= BEGIN TEST Encrypt =========');
    --加密
    encrypted_raw := dbms_crypto.Encrypt(src => raw_input,
					typ => DBMS_CRYPTO.DES3_CBC_PKCS5,
					key => raw_key);

    dbms_output.put_line('> Encrypted hex value : ' || rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
    dbms_output.put_line('> Encrypted varchar2 value: ' || UTL_RAW.CAST_TO_VARCHAR2(encrypted_raw));
    --解密
    decrypted_raw := dbms_crypto.Decrypt(src => encrypted_raw,
					typ => DBMS_CRYPTO.DES3_CBC_PKCS5,
					key => raw_key);
    --将解密后的RAW转换成String
    decrypted_string := UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw);

    dbms_output.put_line('> Decrypted string output : ' || decrypted_string);

    if input_string = decrypted_string THEN
       dbms_output.put_line('> String DES Encyption and Decryption successful');
   END if;
END;
/

运行脚本的结果:
> ========= 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,所以在使用加密时可以使用固定的复杂字符串。

四、自定义加解密函数 https://www.cnblogs.com/zhijiancanxue/p/12507828.html

1、加密

CREATE OR REPLACE FUNCTION F_ENCRYPT_DATA(NUMBER_IN IN VARCHAR2,
                                          SECRETKEY IN VARCHAR2) RETURN RAW IS
  NUMBER_IN_RAW RAW(128) := UTL_I18N.STRING_TO_RAW(NUMBER_IN, 'AL32UTF8');
  KEY_NUMBER    VARCHAR2(32) := SECRETKEY;
  KEY_RAW       RAW(128) := UTL_RAW.CAST_FROM_NUMBER(KEY_NUMBER);
  ENCRYPTED_RAW RAW(128);
BEGIN
  ENCRYPTED_RAW := DBMS_CRYPTO.ENCRYPT(SRC => NUMBER_IN_RAW,
                                       TYP => DBMS_CRYPTO.DES_CBC_PKCS5,
                                       KEY => KEY_RAW);
  RETURN ENCRYPTED_RAW;
END;

2、解密

CREATE OR REPLACE FUNCTION F_DECRYPT_DATA(ENCRYPTED_RAW IN RAW,
                                          SECRETKEY     IN VARCHAR2)
  RETURN VARCHAR2 IS
  DECRYPTED_RAW RAW(128);
  KEY_NUMBER    VARCHAR2(32) := SECRETKEY;
  KEY_RAW       RAW(128) := UTL_RAW.CAST_FROM_NUMBER(KEY_NUMBER);
BEGIN
  DECRYPTED_RAW := DBMS_CRYPTO.DECRYPT(SRC => ENCRYPTED_RAW,
                                       TYP => DBMS_CRYPTO.DES_CBC_PKCS5,
                                       KEY => KEY_RAW);
  RETURN UTL_I18N.RAW_TO_CHAR(DECRYPTED_RAW, 'AL32UTF8');
END;

  

转自:https://www.cnblogs.com/pejsidney/articles/7066032.htmlhttps://www.cnblogs.com/ZTPX/p/10762621.html

posted on 2020-03-21 18:59  渴望飞翔的xian鱼  阅读(1503)  评论(0编辑  收藏  举报

导航