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 org.apache.shiro.codec.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);

    }
}

 

 

posted on 2024-04-12 09:21  西门夜说  阅读(7)  评论(0编辑  收藏  举报