zoukankan      html  css  js  c++  java
  • Oracle加密解密

    Oracle内部有专门的加密包,可以很方便的对内部数据进行加密(encrypt)和解密(decrypt).

      介绍加密包之前,先简单说一下Oracle基本数据类型——RAW类型

      RAW,用于保存位串的数据类型,类似于CHAR,声明方式RAW(L),L为长度,以字节为单位,作为数据库列最大2000,作为变量最大32767字节。

         操作RAW类型的函数:

        utl_raw.cast_to_raw([varchar2]):将varchar2转换为raw类型

        utl_raw.cast_to_varchar2([raw]):将raw转换为varchar2类型

        hextoraw():十六进制字符串转换为raw

        rawtohex():将raw串转换为十六进制

          注:RAW保存的为16进制数,当使用HEXTORAW时,会把字符串中数据当作16进制数。而使用UTL_RAW.CAST_TO_RAW时,直接把字符串中每个字符的ASCII码存放到RAW类型的字段中。

               eg>select hextoraw('abc') from dual;    --输出结果为: ABC

        eg>select utl_raw.cast_to_raw('abc') from dual;    --输出结果为: 616263(a的ASCII码值为97,转换成16进制数为61)

    下面介绍一下Oracle中的加密包:

    1,Dbms_Obfuscation_Toolkit(9i)

      利用Dbms_Obfuscation_Toolkit包,我们可以对数据进行DES,Triple DES或者MD5加密

         DESGETKEY   -- 产生密钥,用于DES算法
         DES3GETKEY  -- 产生密钥,用于Triple DES算法
         DESENCRYPT  -- 用DES算法加密数据
         DESDECRYPT  -- 用DES算法解密数据
         DES3ENCRYPT -- 用Triple DES算法加密数据
         DES3DECRYPT -- 用DES算法解密数据
         MD5         -- 用MD5算法加密数据

      加密包中分别采用raw和string两种数据类型加密,分别测试一下:(注:加密的字符串(input_string)必须是8的倍数)

    DES算法加密解密

    DECLARE
      v_input VARCHAR2(100) := '12345678';
      v_key   VARCHAR2(100) := 'oracle9i';
      -- ORA-28232: obfuscation 工具箱的输入长度无效(原因是加密字符串必须是8的倍数)
    
      encrypted_str VARCHAR2(4000);
      decrypted_str VARCHAR2(4000);
      encrypted_raw RAW(4000);
      decrypted_raw RAW(4000);
    BEGIN
      -- string类型加密解密
      -- encrypt(string)
      dbms_obfuscation_toolkit.desencrypt(input_string => v_input, key_string => v_key, encrypted_string => encrypted_str);
      dbms_output.put_line('Encrypted string: ' || encrypted_str);
      dbms_output.put_line('Encrypted hex value: ' || utl_raw.cast_to_raw(encrypted_str));
      -- decrypt(string)
      dbms_obfuscation_toolkit.desdecrypt(input_string => encrypted_str, key_string => v_key, decrypted_string => decrypted_str);
      dbms_output.put_line('Decrypted String: ' || decrypted_str);
    
      -- raw类型加密解密
      -- encrypt(raw)
      dbms_obfuscation_toolkit.desencrypt(input => utl_raw.cast_to_raw(v_input), key => utl_raw.cast_to_raw(v_key), encrypted_data => encrypted_raw);
      dbms_output.put_line('Encrypted Raw: ' || encrypted_raw);
      dbms_output.put_line('Encrypted hex value: ' || rawtohex(encrypted_raw));
      -- decrypt(raw)
      dbms_obfuscation_toolkit.desdecrypt(input => encrypted_raw, key => utl_raw.cast_to_raw(v_key), decrypted_data => decrypted_raw);
      dbms_output.put_line('Decrypted String: ' || utl_raw.cast_to_varchar2(decrypted_raw));
    END;
    

    注:DES算法加密的key长度必须大于等于8,而且加密的结果只跟其前8位有关(推测可能是截取了字符串);

    Triple DES算法加密(DES3ENCRYPT)用法同DES基本类似,安全性叫DES算法更高;

        同理,Triple DES算法的key长度必须大于等于16,且结果只与其前16位有关;

     (Extra:数据类型PLS_INTEGER可以存储一个有符号的整型值,其精度范围和BINARY_INTEGER一样,是-2^31~2^31

    MD5算法加密

    DECLARE
      v_str VARCHAR2(100) := '123456';
      v_key VARCHAR2(100) := 'oracle9i';
      
      encrypted_str VARCHAR2(32);
      encrypted_raw RAW(32);
    BEGIN
      -- encrypted as string
      dbms_obfuscation_toolkit.MD5(input_string => v_str || v_key, checksum_string => encrypted_str);
      dbms_output.put_line('Encrypted String: ' || encrypted_str);
      dbms_output.put_line('Encrypted hex value: ' || utl_raw.cast_to_raw(encrypted_str));
      
      -- encrypted as raw
      dbms_obfuscation_toolkit.MD5(input => utl_raw.cast_to_raw(v_str || v_key), checksum => encrypted_raw);
      dbms_output.put_line('Encrypted Raw: ' || encrypted_raw);
      dbms_output.put_line('Encrypted hex value: ' || rawtohex(encrypted_raw));
    END;
    

     注:MD5算法只能正向加密,但它多次对于同一数据的加密计算结果是相同的。

    2,dbms_crypto(10g以后)

      dbms_crypto包默认只有sysdba用户才可执行,其他任何用户都需要sysdba进行授权

      sys>grant execute on dbms_crypto to scott;

    -- 示例(不考虑BLOB类型的加密)
    DECLARE v_str VARCHAR2(20) := '12345678'; -- 加密的字符串 v_type PLS_INTEGER := dbms_crypto.DES_CBC_PKCS5; -- 加密类型 v_key RAW(256); v_key1 VARCHAR2(100) := 'oracle9i012'; encrypted_raw RAW(256); decrypted_raw RAW(256); BEGIN -- 生成随机16位密钥 (1个byte等于两位raw) v_key := dbms_crypto.RandomBytes(8); dbms_output.put_line('Encrypted Key: ' || v_key); -- 加密 encrypted_raw := dbms_crypto.Encrypt(src => utl_raw.cast_to_raw(v_str), typ => v_type, key => v_key); dbms_output.put_line('Encrypted Raw: ' || encrypted_raw); dbms_output.put_line('Encrypted hex value: ' || rawtohex(encrypted_raw)); -- 解密 decrypted_raw := dbms_crypto.Decrypt(src => encrypted_raw, typ => v_type, key => v_key); dbms_output.put_line('Decrypted String: ' || utl_raw.cast_to_varchar2(decrypted_raw)); END;

     可以加加密和解密的内容写入函数中,方便使用的时候直接调用。

  • 相关阅读:
    SourceInsight中文字体
    Android Studio导入第三方类库的方法
    Unable to create Debug Bridge:Unable to start adb server:error:cannot parse version
    match_parent 、 fill_parent 、 wrap_content
    android:textAppearance
    AndroidManifest配置之uses-sdk
    从Github上下载了项目,导入Android Studio,gradle 报错,应该怎么修改
    Android Studio 使用Gradle多渠道打包
    Android Studio常用快捷键
    在一个form表单中根据不同按钮实现多个action事件
  • 原文地址:https://www.cnblogs.com/colaclicken/p/10972444.html
Copyright © 2011-2022 走看看