oracle:加密解密
授权用户使用DBMS_CRYPTO 包
GRANT EXECUTE ON DBMS_CRYPTO TO 用户名;
-- 加密函数 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:加密解密
-- 加密函数 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); } }