【PB续命02】Oracle中加密及编码等

Oracle中实现Md5/Base64/Aes+Base64/UrlEncode等加密编码的使用备忘,参考其它人的贴子,Oracle 11g 亲测有效。

1. Oracle中实现Md5加密

SELECT lower(MD5('白龙马5217')) FROM dual;
--返回结果 72853926982028ab8219921ad2918b8f
--或 
select  utl_raw.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING => '白龙马5217')) from dual
--返回结果 72853926982028AB8219921AD2918B8F

2. Oracle中实现Base64编码/解码

--2.1.编码:
select utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw('白龙马5217'))) from dual
-- 输出: sNfB+sLtNTIxNw== 
--2.2. 解码:
select (utl_raw.cast_to_varchar2(utl_encode.base64_decode(utl_raw.cast_to_raw('sNfB+sLtNTIxNw==')))) as 结果 from dual
-- 输出: 白龙马5217

3. Oracle中实现UrlEncode和UrlDecode

-- 3.1.UrlEncode ,创建方法如下:
CREATE OR REPLACE FUNCTION url_encode(urlEncode IN VARCHAR2)
RETURN VARCHAR2 AS
BEGIN--utl_url.escape()该方法只能在函数中调用
    RETURN utl_url.escape(urlEncode, TRUE, 'utf-8');
END;
-- 3.2. UrlEncode使用实例:

SELECT url_encode('http://www.cnblogs.com/Marydon20170307?param=测试URL编码') FROM DUAL;
-- 输出: http%3A%2F%2Fwww.cnblogs.com%2FMarydon20170307%3Fparam%3D%E6%B5%8B%E8%AF%95URL%E7%BC%96%E7%A0%81
-- 3.3. UrlDecode ,直接使用一条Sql即可:
SELECT utl_url.unescape('待进行Url解码的字符串','utf-8') FROM DUAL;

-- 实例:
SELECT utl_url.unescape('http%3A%2F%2Fwww.cnblogs.com%2FMarydon20170307%3Fparam%3D%E6%B5%8B%E8%AF%95URL%E7%BC%96%E7%A0%81','utf-8') FROM DUAL;
-- 输出:http://www.cnblogs.com/Marydon20170307?param=测试URL编码

4. Oracle中实现Aes + Base64:加密/解密 [Aes的Key为16位]

-- 4.1. 登录sys用户as SYSDBA,执行授权,如果不想公开public,也可指定要授权的用户,如blma  
--		conn / as sysdba 
grant execute on sys.dbms_crypto to public; --需要管理员角色登录才能执行
grant execute on sys.UTL_I18N to public;

-- 	*** 注意 ***: 授权完成,切换自己的用户
--    conn / as Normal
-- 4.2. 创建加密函数 ==> Aes+Base64
CREATE OR REPLACE FUNCTION fn_EnAes64(as_ysj IN VARCHAR2,as_key In Varchar2)
RETURN VARCHAR2
IS
   encrypted_raw      RAW (2000);                                     -- 储存加密后的字节
   key_bytes_raw      RAW (16);                                       -- 储存秘钥 128比特 (16位)
   -- 我这里的Aes加解密方式为: AES/ECB/PKCS5Padding ,  自己可自由组合,如:AES/ECB/PKCS5Padding等等
   encryption_type    PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES + DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_PKCS5 ; 
   iv_raw             RAW (16);                               -- 向量
BEGIN
   -- 秘钥
   key_bytes_raw := UTL_I18N.STRING_TO_RAW(as_key,'AL32UTF8'); -- DBMS_CRYPTO.RANDOMBYTES (num_key_bytes);
   -- 向量 
   iv_raw        := UTL_I18N.STRING_TO_RAW('9iuj87y2hbi5wxl1','AL32UTF8'); -- DBMS_CRYPTO.RANDOMBYTES (16);
   
   -- 加密过程
   encrypted_raw := DBMS_CRYPTO.ENCRYPT
      (
         src => UTL_I18N.STRING_TO_RAW (as_ysj,  'AL32UTF8'),
         typ => encryption_type,
         key => key_bytes_raw,
         iv  => iv_raw
      );

   -- Bas64加密,如果只要aes,不需要base64,则此步注释跳过即可
   encrypted_raw := utl_encode.base64_encode(r => encrypted_raw);

   return UTL_I18N.RAW_TO_CHAR (encrypted_raw, 'AL32UTF8');
END;

-- 4.3. 创建解密函数 ==> Aes+Base64
CREATE OR REPLACE FUNCTION fn_DeAes64(as_ysj IN VARCHAR2, as_key IN VARCHAR2)
RETURN VARCHAR2
IS
   decrypted_raw      RAW (2000);                                     -- 储存解密后的字节
   key_bytes_raw      RAW (16);                                       -- 储存秘钥 128比特 (16位)
   -- 我这里的Aes加解密方式为: AES/ECB/PKCS5Padding ,  自己可自由组合,如:AES/ECB/PKCS5Padding等等
   encryption_type    PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES + DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_PKCS5 ; 	
   iv_raw             RAW (16);                               -- 向量
   temp               varchar2(1000);                         -- 临时,AES加密并Base64后的结果
BEGIN
   -- 秘钥
   key_bytes_raw := UTL_I18N.STRING_TO_RAW( as_key,'AL32UTF8'); -- DBMS_CRYPTO.RANDOMBYTES (num_key_bytes);
   -- 向量
   iv_raw        := UTL_I18N.STRING_TO_RAW('9iuj87y2hbi5wxl1','AL32UTF8'); -- DBMS_CRYPTO.RANDOMBYTES (16);

   -- 将加密后字符串转为row
   decrypted_raw  := utl_raw.cast_to_raw(c => as_ysj);
   
   -- Base64解密, 如果源字符串仅aes加密,没有base64编码,则此步注释跳过即可
   decrypted_raw := utl_encode.base64_decode(r => decrypted_raw);

    -- Aes解密
    decrypted_raw := DBMS_CRYPTO.DECRYPT
      (
         src => decrypted_raw,
         typ => encryption_type,
         key => key_bytes_raw,
         iv  => iv_raw
      );
   temp := UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8');
   RETURN temp;
END;

--4.4. 应用示例,密钥只能为16位
select fn_enaes64('白龙马5217','blma5217blma5217') from dual
--加密后的结果: mV4aaEnbaEllRvpH5WSiyw==
select fn_deaes64('mV4aaEnbaEllRvpH5WSiyw==','blma5217blma5217') from dual
--解密后的结果: 白龙马5217

5. 实现Aes192加密/解密 [Key为24位]

--5.1.sys授权、创建Aes加密、Aes解密方法
--  登录sys用户,执行授权,如果不想公开public,也可指定要授权的用户,如scott    
--    conn / as sysdba 
grant execute on sys.dbms_crypto to public;
grant execute on sys.UTL_I18N to public;

--   *** 注意 ***: 授权完成,切换自己的用户
-- 5.2.加密函数
CREATE OR REPLACE FUNCTION FN_ENAES192(
    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
    V_KEY_RAW := UTL_I18N.STRING_TO_RAW(V_KEY,'UTF8') ;
    V_STR_RAW := UTL_I18N.STRING_TO_RAW(V_STR,'UTF8') ;
    V_TYPE := DBMS_CRYPTO.ENCRYPT_AES192+DBMS_CRYPTO.CHAIN_CBC+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 ;
END;

-- 5.3. 解密函数
CREATE OR REPLACE FUNCTION FN_DEAES192(
    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
    V_KEY_RAW := UTL_I18N.STRING_TO_RAW(V_KEY,'UTF8') ;
    V_STR_RAW := HEXTORAW(V_STR);
    V_TYPE := DBMS_CRYPTO.ENCRYPT_AES192+DBMS_CRYPTO.CHAIN_CBC+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,'UTF8');
    RETURN V_RETURN_STR ;
END;


--5.4. Aes192加密/解密使用实例
select -- 加密字符串:白龙马5217 Key: 0123456789abcd0123456789
  FN_ENAES192('白龙马5217','0123456789abcd0123456789')    -- 加密
from dual;
--加密结果: 7A868850953737C8F0DB44E8B1D14C12

select -- 解密字符串: 7A868850953737C8F0DB44E8B1D14C12   key: 0123456789abcd0123456789
  FN_DEAES192('7A868850953737C8F0DB44E8B1D14C12','0123456789abcd0123456789')   -- 解密
from dual;
--解密结果: 白龙马5217

6. 实现Des算法加密解密

DES加解密算法的明文和密钥长度必须为8的倍数。

6.1 DES加密String类型

create or replace function FN_ENDES_STRING(input8x in varchar2,key8x in varchar2) return varchar2 is
  RetuenResult varchar2(4000);
  
  encrypted_str VARCHAR2(4000);
 
begin
  --input_string 和 key_string 的长度必须是8的倍数
  dbms_obfuscation_toolkit.desencrypt(input_string => input8x, key_string => key8x, encrypted_string => encrypted_str);
  --RetuenResult := utl_raw.cast_to_raw(encrypted_str);
  RetuenResult := encrypted_str;
  return(RetuenResult);
end FN_ENDES_STRING;

FN_ENDES_STRING()应用示例

select fn_endes_string('BLMA5217','12345678') from dual
--返回结果:AFAC8E02619B59E0

6.2 DES解密String类型

create or replace function FN_DEDES_STRING(encrypted_str in varchar2,key8x in varchar2) return varchar2 is
   -- encrypted_str为FN_ENDES_STRING()的返回值
   -- key_string 的长度必须是8的倍数
   
   RetuenResult varchar2(4000);
  
   decrypted_str VARCHAR2(4000);
begin
   
   dbms_obfuscation_toolkit.desdecrypt(
     input_string => utl_raw.cast_to_varchar2(encrypted_str), 
     key_string => key8x, 
     decrypted_string => decrypted_str);
   RetuenResult := decrypted_str;
   return(RetuenResult);
end FN_DEDES_STRING;

FN_DEDES_STRING()应用示例

select fn_dedes_string('AFAC8E02619B59E0','12345678') from dual
--返回结果:BLMA5217

6.3 DES加密Raw类型

create or replace function FN_ENDES_RAW(input8x in varchar2,key8x in varchar2) return varchar2 is
--input_string 和 key_string 的长度必须是8的倍数
  RetuenResult varchar2(4000);
  
  encrypted_raw RAW(4000);
  decrypted_raw RAW(4000);
begin
  
  dbms_obfuscation_toolkit.desencrypt
     (input => utl_raw.cast_to_raw(input8x), 
      key => utl_raw.cast_to_raw(key8x), 
      encrypted_data => encrypted_raw);
  RetuenResult := rawtohex(encrypted_raw);
  return(RetuenResult);
end FN_ENDES_RAW;

FN_ENDES_RAW()应用示例

select fn_endes_raw('BLMA5217','12345678') from dual
--返回结果:AFAC8E02619B59E0

6.4 DES解密Raw类型

create or replace function FN_DEDES_RAW(encrypted_raw in varchar2,key8x in varchar2) return varchar2 is
-- encrypted_raw 为FN_ENDES_RAW()的返回值
-- key_string 的长度必须是8的倍数

  RetuenResult varchar2(4000);
  
  decrypted_raw RAW(4000);
begin
  
  dbms_obfuscation_toolkit.desdecrypt
     (input => encrypted_raw, 
      key => utl_raw.cast_to_raw(key8x), 
      decrypted_data => decrypted_raw);
  RetuenResult := utl_raw.cast_to_varchar2(decrypted_raw);
  return(RetuenResult);
end FN_DEDES_RAW;

FN_ENDES_RAW()应用示例

select fn_dedes_raw('AFAC8E02619B59E0','12345678') from dual
--返回结果:BLMA5217

7. Oracle10以后的通用加密/解密 ==> dbms_crypto

说明:

dbms_crypto包默认只有sysdba用户才可执行,

其他任何用户都需要sysdba进行授权 conn / as sysdba;

sys> grant execute on dbms_crypto to scott;

如需要其它加密算法可自己查阅。

(完)

相关推荐
成富1 分钟前
文本转SQL(Text-to-SQL),场景介绍与 Spring AI 实现
数据库·人工智能·sql·spring·oracle
songqq272 分钟前
SQL题:使用hive查询各类型专利top 10申请人,以及对应的专利申请数
数据库·sql
计算机学长felix5 分钟前
基于SpringBoot的“校园交友网站”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·毕业设计·交友
小码的头发丝、1 小时前
Django中ListView 和 DetailView类的区别
数据库·python·django
Karoku0661 小时前
【企业级分布式系统】Zabbix监控系统与部署安装
运维·服务器·数据库·redis·mysql·zabbix
周全全2 小时前
MySQL报错解决:The user specified as a definer (‘root‘@‘%‘) does not exist
android·数据库·mysql
白云如幻2 小时前
MySQL的分组函数
数据库·mysql
荒川之神2 小时前
ORACLE 闪回技术简介
数据库·oracle
时差9533 小时前
【面试题】Hive 查询:如何查找用户连续三天登录的记录
大数据·数据库·hive·sql·面试·database
让学习成为一种生活方式3 小时前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言