oracle:加密解密
授权用户使用DBMS_CRYPTO 包
GRANT EXECUTE ON DBMS_CRYPTO TO 用户名;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | -- 加密函数 zcc CREATE OR REPLACE FUNCTION aes_128_cbc_encrypt_function( p_input VARCHAR2, p_key VARCHAR2, p_iv VARCHAR2 ) RETURN VARCHAR2 IS encrypted_raw varchar2( 2000 ); BEGIN encrypted_raw := DBMS_CRYPTO.Encrypt( src => utl_raw.cast_to_raw(CONVERT(p_input, 'AL32UTF8' )), typ => DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5, key => utl_raw.cast_to_raw(p_key), iv => utl_raw.cast_to_raw(p_iv) ); DBMS_OUTPUT.PUT_LINE( 'RAW Data: ' || encrypted_raw); RETURN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.base64_encode(encrypted_raw)); END; -- 解密函数 zcc CREATE OR REPLACE FUNCTION aes_128_cbc_decrypt_function( p_input VARCHAR2, p_key VARCHAR2, p_iv VARCHAR2 ) RETURN VARCHAR2 IS decrypted_raw VARCHAR2( 2000 ); BEGIN -- 密文 -- decrypted_raw := utl_raw.cast_to_raw(c => p_input); -- Base64 解密 -- decrypted_raw := utl_encode.base64_decode(r => decrypted_raw); decrypted_raw := DBMS_CRYPTO.DECRYPT( src => UTL_ENCODE.BASE64_DECODE(utl_raw.cast_to_raw(p_input)), -- src => decrypted_raw, typ => DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5, key => utl_raw.cast_to_raw(p_key), iv => utl_raw.cast_to_raw(p_iv) ); DBMS_OUTPUT.PUT_LINE( 'RAW Data: ' || decrypted_raw); RETURN UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8' ); END; |
测试:
加密
解密
mysql:加密解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | -- 加密函数 zcc CREATE DEFINER=`root`@`%` FUNCTION `aes_128_cbc_encrypt_function`( p_input VARCHAR( 255 ), p_key VARCHAR( 255 ), p_iv VARCHAR( 255 ) ) RETURNS varchar( 255 ) CHARSET utf8mb4 DETERMINISTIC BEGIN DECLARE encrypted_text BLOB; SET block_encryption_mode = 'AES-128-CBC' ; SET encrypted_text = AES_ENCRYPT( p_input, p_key, p_iv ); RETURN TO_BASE64(encrypted_text); END -- 解密函数 zcc CREATE DEFINER=`root`@`%` FUNCTION `aes_128_cbc_decrypt_function`( p_input VARCHAR( 255 ), p_key VARCHAR( 255 ), p_iv VARCHAR( 255 ) ) RETURNS varchar( 255 ) CHARSET utf8mb4 DETERMINISTIC BEGIN DECLARE decrypted_text TEXT; SET block_encryption_mode = 'AES-128-CBC' ; SET decrypted_text = AES_DECRYPT( FROM_BASE64(p_input), p_key, p_iv ); RETURN decrypted_text; END |
package com.frkj.common.util.encryption; import java.util.Base64;
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; /** * zcc */ public class Aes128CbcEncryptUtil { //使用AES-128-CBC加密模式,key和iv需要为16位,key和iv可以相同! /** * 使用AES-128-CBC加密模式 */ private static String KEY = "100860147qwertyu"; private static String IV = "10010963.zxcvbnm"; /** * 加密方法 * @param data 要加密的数据 * @param key 加密key * @param iv 加密iv * @return 加密的结果 * @throws Exception */ public static String encrypt(String data, String key, String iv) throws Exception { try { //"AES":AES(高级加密标准)是一种广泛使用的对称密钥加密算法 //"CBC" CBC(串行密钥传输)模式 //CBC是一种比ECB更加安全的加密模式。在CBC模式中,每个数据块都被分成两个部分:明文和密钥。第一个数据块被称为“前向块”,第二个数据块被称为“后向块”。前向块的密文是由密钥和前向块一起计算得到的,而后向块的密文则是由密钥和后向块一起计算得到的。这种模式可以确保即使攻击者能够获得密钥的一部分,也无法解密整个数据块。但是,CBC模式的速度较慢,因为需要处理大量的中间结果 //Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");//"算法/模式/补码方式"NoPadding PkcsPadding //PKCS5Padding是一种常见的填充算法,用于填充数据以符合AES模式的要求。这种填充方式使用一个固定长度的填充字节序列,以确保输入数据被完全填充。PKCS#5 padding的优点是它可以适应各种输入数据的大小,但缺点是填充过程可能很慢。 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//"算法/模式/补码方式"NoPadding PKCS5Padding SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)); return Base64.encodeToString(encrypted); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 解密方法 * @param data 要解密的数据 * @param key 解密key * @param iv 解密iv * @return 解密的结果 * @throws Exception */ public static String desEncrypt(String data, String key, String iv) throws Exception { try { byte[] encrypted1 = Base64.decode(data); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); byte[] original = cipher.doFinal(encrypted1); String originalString = new String(original, StandardCharsets.UTF_8); return originalString.trim(); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 使用默认的key和iv加密 * @param data * @return * @throws Exception */ public static String encrypt(String data) throws Exception { return encrypt(data, KEY, IV); } /** * 使用默认的key和iv解密 * @param data * @return * @throws Exception */ public static String desEncrypt(String data) throws Exception { return desEncrypt(data, KEY, IV); } public static void main(String[] args) throws Exception { String encrypt = encrypt("你好"); System.out.println("加密数据:"+encrypt); String s = desEncrypt(encrypt); System.out.println("解密密数据:"+s); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
2020-04-12 类加载器、反射、模块化