zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    在win7系统下安装把Ubuntu17.04安装在另一个硬盘开机无法进入Ubuntu问题的一种解决办法。【转】
    快速上手Ubuntu之安装篇——安装win7,Ubuntu16.04双系统【转】
    win7 64位系统与Ubuntu14.04 64位系统双系统安装【转】
    kernel中对文件的读写【学习笔记】【原创】
    快速解决Android中的selinux权限问题【转】
    Android如何配置init.rc中的开机启动进程(service)【转】
    linux内核驱动中对文件的读写 【转】
    很好的 DHCP协议与dhcpcd分析【转】
    android DHCP流程【转】
    Android wifi 从连接态自动断开的解决办法(dhcp导致)【转】
  • 原文地址:https://www.cnblogs.com/shujk/p/12541391.html
Copyright © 2011-2022 走看看