zoukankan      html  css  js  c++  java
  • ORACLE 字段AES算法加密、解密函数索引

    --我这里使用的是utl_i18n.string_to_raw进行数据类型的转换,这是因为encrypt函数不但需要raw型数据,而且还需要使用专门的字符集—AL32UTF8,这里如果使用utl_raw.cast_to_raw,则会出现“ORA-06512”错误。
    --只需要对解密函数写deterministic确定性函数
    grant execute on SYS.DBMS_CRYPTO to enc;

    create or replace function enc.encrypt(v_string in varchar2) return varchar2 is
    encrypted_raw RAW (2000);
    encryption_type PLS_INTEGER := SYS.DBMS_CRYPTO.ENCRYPT_DES + SYS.DBMS_CRYPTO.CHAIN_CBC + SYS.DBMS_CRYPTO.PAD_PKCS5;
    v_key raw(128) := utl_i18n.string_to_raw( 'artos0011', 'AL32UTF8' );
    begin
    encrypted_raw := DBMS_CRYPTO.ENCRYPT
    (
    src => UTL_I18N.STRING_TO_RAW (v_string,'AL32UTF8'),
    typ => encryption_type,
    key => v_key
    );
    return RAWTOHEX(encrypted_raw);
    end encrypt;
    /

    create or replace function enc.decrypt(v_str in varchar2) return varchar2 is
    decrypted_raw raw(2000);
    encryption_type PLS_INTEGER := SYS.DBMS_CRYPTO.ENCRYPT_DES + SYS.DBMS_CRYPTO.CHAIN_CBC + SYS.DBMS_CRYPTO.PAD_PKCS5;
    v_key raw(128) := utl_i18n.string_to_raw( 'artos001', 'AL32UTF8' );
    begin
    decrypted_raw := DBMS_CRYPTO.Decrypt
    (
    src => HEXTORAW(v_str),
    typ => encryption_type,
    key => v_key
    );
    return UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8');
    end decrypt;
    /

    select enc.encrypt('67634572') from dual;
    select enc.decrypt(enc.encrypt('67634572')) from dual;

    ------------------------------------------------------------------------------------------------------------------------------------
    --函数索引,对自定义解密函数
    CREATE TABLE ENC.A34(ID NUMBER PRIMARY KEY,NAME VARCHAR2(200),ADDR VARCHAR2(200));

    BEGIN
    FOR I IN 1..10000 LOOP
    INSERT INTO ENC.A34 SELECT I,'N'||I,'A'||I FROM DUAL;
    END LOOP;
    COMMIT;
    END;
    /

    ALTER TABLE ENC.A34 ADD NAME_ VARCHAR2(4000);
    CREATE VIEW ENC.V_A34 AS SELECT ID,ENC.DECRYPT(NAME_) AS NAME,ADDR FROM ENC.A34;
    UPDATE ENC.A34 T SET T.NAME_=ENC.ENCRYPT(NAME);
    COMMIT;

    CREATE INDEX ENC.IDX_NAME_ ON ENC.A34(ENC.DECRYPT(NAME_));
    --收集表统计信息
    call dbms_stats.gather_table_stats(ownname => 'ENC',tabname => '"A34"',estimate_percent => 10,method_opt=> 'for all indexed columns');
    call dbms_stats.gather_table_stats(ownname => 'ENC',tabname => '"A34"',CASCADE=>TRUE);

    SELECT T.*,ENC.DECRYPT(T.NAME_) FROM ENC.A34 T WHERE T.ID='4';
    SELECT /*+index(t IDX_NAME_)*/* FROM ENC.A34 T WHERE ENC.DECRYPT(NAME_)>='N4';
    SELECT /*+index(t IDX_NAME_)*/* FROM ENC.A34 T WHERE ENC.DECRYPT(NAME_) = 'N44';
    SELECT * FROM ENC.V_A34 T WHERE T.NAME='N44';
    UPDATE ENC.A34 T SET T.NAME_=ENC.ENCRYPT(T.NAME||'4') WHERE T.ID=4;

    --查看执行计划
    EXPLAIN PLAN FOR SELECT * FROM ENC.A34 T WHERE T.NAME='N2';
    SELECT * FROM table(DBMS_XPLAN.DISPLAY);

    --SYS.DBMS_CRYPTO.ENCRYPT_DES为包变量,不能在sql中调用
    SELECT SYS.DBMS_CRYPTO.ENCRYPT_DES + SYS.DBMS_CRYPTO.CHAIN_CBC + SYS.DBMS_CRYPTO.PAD_PKCS5 FROM DUAL;

    ------------------------------------------------------------------------------------------------------------------------------------
    ORACLE 字段AES算法加密、解密(解决中文乱码问题)
    1.加解密函数入口

    CREATE OR REPLACE FUNCTION F_ZNMH_SMK_CRYPT(P_SRC IN VARCHAR2,
    P_TYPE IN NUMBER)
    RETURN VARCHAR2 IS
    RESULT VARCHAR2(4000);

    BEGIN
    /*************************************************
    信息加密函数 F_ZNMH_SMK_CRYPT 
    入参:
    P_SRC 输入明文字符串
    P_TYPE 处理类型,1,为加密;2,为解密;
    返回值:
    RESULT 返回密文字符串,约定返回为 16进制密文字符串
     异常处理:
    此函数不对任何异常做捕捉处理,请相应的程序模块对异常做捕捉处理。

    加密方式:
    密钥位数:AES192 DBMS_CRYPTO.ENCRYPT_AES192
    连接方式:CBC DBMS_CRYPTO.CHAIN_CBC
    填充方式:PKCS5 DBMS_CRYPTO.PAD_PKCS5
    默认密钥:
    KEY ZNMH1234
    **************************************************/
    DECLARE
    KEY VARCHAR2(20);

    BEGIN
    KEY := 'ZNMH1234';
    RESULT := 'ERROR ENCRPT INFO';

    --P_TYPE为1时,代表加密;2时,代表解密;
    IF (P_TYPE = 1) THEN
    RESULT := ENCRYPT_FUNCTION(P_SRC, KEY);
    ELSIF (P_TYPE = 2) THEN
    RESULT := DECRYPT_FUNCTION(P_SRC, KEY);
    END IF;
    EXCEPTION
    WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('SQLCODE : ' || SQLCODE);
    DBMS_OUTPUT.PUT_LINE('SQLERRM : ' || SQLERRM);
    RETURN(RESULT);
    END;
    RETURN(RESULT);
    END F_ZNMH_SMK_CRYPT;

    2.加密函数

    CREATE OR REPLACE FUNCTION ENCRYPT_FUNCTION(
    V_STR VARCHAR2, V_KEY VARCHAR2) RETURN VARCHAR2 AS V_KEY_RAW RAW(24);
    V_STR_RAW RAW(2000);
    V_RETURN_STR VARCHAR2(2000);
    V_TYPE PLS_INTEGER;
    BEGIN
    /*************************************************
    加密函数 FUN_ENCRYPTION 
    入参:
    V_STR 输入明文字符串
    V_KEY 输入密钥字符串,长度为24字节
    返回值:
    V_RETURN_STR 返回密文字符串,约定返回为 16进制密文字符串
     异常处理:
    此函数不对任何异常做捕捉处理,请相应的程序模块对异常做捕捉处理。

    加密方式:
    密钥位数:AES192 DBMS_CRYPTO.ENCRYPT_AES192
    连接方式:CBC DBMS_CRYPTO.CHAIN_CBC
    填充方式:PKCS5 DBMS_CRYPTO.PAD_PKCS5

    **************************************************/
    V_KEY_RAW := UTL_I18N.STRING_TO_RAW(V_KEY, 'ZHS16GBK');
    V_STR_RAW := UTL_I18N.STRING_TO_RAW(V_STR, 'ZHS16GBK');
    -- 指定‘密钥算法’、‘工作模式’、‘填充方式’
    V_TYPE := DBMS_CRYPTO.ENCRYPT_DES + DBMS_CRYPTO.CHAIN_ECB +
    DBMS_CRYPTO.PAD_PKCS5;
    V_STR_RAW := DBMS_CRYPTO.ENCRYPT(SRC => V_STR_RAW,
    TYP => V_TYPE,
    KEY => V_KEY_RAW);
    V_RETURN_STR := RAWTOHEX(V_STR_RAW);
    RETURN V_RETURN_STR;

    /* EXCEPTION
    WHEN OTHERS THEN
    RETURN SQLERRM||SQLCODE ; */
    END;


    3.解密函数

    CREATE OR REPLACE FUNCTION DECRYPT_FUNCTION(V_STR VARCHAR2, V_KEY VARCHAR2)
    RETURN VARCHAR2 AS
    V_KEY_RAW RAW(24);
    V_STR_RAW RAW(2000);
    V_RETURN_STR VARCHAR2(2000);
    V_TYPE PLS_INTEGER;

    BEGIN
    /************************************************
    解密函数 FUN_DECRYPTION 
    入参:
    V_STR 输入密文字符串,约定密文为16进制字符串
    V_KEY 输入密钥字符串,长度为24字节
    返回值:
    V_RETURN_STR 返回明文字符串
    异常处理:
    此函数不对任何异常做捕捉处理,请相应的程序模块对异常做捕捉处理。

    加密方式:
    密钥位数:AES192 DBMS_CRYPTO.ENCRYPT_AES192
    连接方式:CBC DBMS_CRYPTO.CHAIN_CBC
    填充方式:PKCS5 DBMS_CRYPTO.PAD_PKCS5

    ***************************************************/
    V_KEY_RAW := UTL_I18N.STRING_TO_RAW(V_KEY, 'ZHS16GBK');
    V_STR_RAW := HEXTORAW(V_STR);
    -- 指定‘密钥算法’、‘工作模式’、‘填充方式’
    V_TYPE := DBMS_CRYPTO.ENCRYPT_DES + DBMS_CRYPTO.CHAIN_ECB +
    DBMS_CRYPTO.PAD_PKCS5;
    V_STR_RAW := DBMS_CRYPTO.DECRYPT(SRC => V_STR_RAW,
    TYP => V_TYPE,
    KEY => V_KEY_RAW);
    V_RETURN_STR := UTL_I18N.RAW_TO_CHAR(V_STR_RAW, 'ZHS16GBK');
    RETURN V_RETURN_STR;
    /* EXCEPTION
    WHEN OTHERS THEN
    RETURN SQLERRM||SQLCODE ; */
    END;

  • 相关阅读:
    阅读笔记:管理学
    Vs2010中文版MSDN 安装方法
    .NET 产品版权保护方案 (.NET源码加密保护)
    WPF 判断是否为设计(Design)状态
    重写成员时违反了继承安全性规则。重写方法的安全可访问性必须与所重写方法的安全可访问性匹配。
    没有为此解决方案配置选中要生成的项目 .
    何崚谈阿里巴巴前端性能优化最佳实践
    Oracle10GODP连接11G数据库,出现ORA 1017用户名/口令无效; 登录被拒绝 的问题
    HTTP、TCP、UDP、Socket (转)
    编译的时候生成.g.cs还有.g.i.cs,有什么区别?
  • 原文地址:https://www.cnblogs.com/buffercache/p/10209382.html
Copyright © 2011-2022 走看看