GBase8c aes_encrypt和aes_decrypt函数

在数据库中,aes_encrypt和aes_decrypt函数进行加解密时使用的块加密模式。

GBase8c 与 MySQL 的aes_encrypt和aes_decrypt函数区别:
1、GBase8c 中的初始化向量init_vector不能为空
2、MySQL的加密模块block_encryption_mode 为aes-128-ecb,GBase8c 不支持aes-128-ecb,默认加密模块为aes-128-cbc
3、GBase8c 中该函数仅在MY兼容模式时(即sql_compatibility = ‘B’)有效,其他类型不支持该函数。
4、初始化向量init_vector需要大于16字节

aes_encrypt(str, key_str, init_vector)

描述:基于AES算法,使用密钥字符串key_str和初始化向量init_vector对字符串str进行加密。

参数解释:
-- str:需要被加密的字符串。若str为NULL,函数返回NULL。

-- key_str:密钥字符串。若key_str为NULL,函数返回NULL。为了安全,对于128bit/192bit/256bit的密钥长度(由块加密模式block_encryption_mode确定,参数介绍请参见安全配置),建议用户使用128bit/192bit/256bit的安全随机数作为密钥字符串。

-- init_vector:为需要它的块加密模式提供初始化变量,长度大于等于16字节(大于16的字节会被在自动忽略)。str和key_str均不为NULL时,该参数不可为NULL,否则报错。为了安全,建议用户在OFB模式下,保证每次加密IV值的唯一性;在CBC模式和CFB模式下,保证每次加密的IV值不可被预测。

返回值类型:text

aes_decrypt(pass_str, key_str, init_vector)

描述:基于AES算法,使用密钥字符串key_str和初始化向量init_vector对字符串str进行解密。

参数解释:
-- pass_str:需要被解密的字符串。若pass_str为NULL,函数返回NULL。

-- key_str: 密钥字符串。若key_str为NULL,函数返回NULL。为了安全,对于128bit/192bit/256bit的密钥长度(由块加密模式block_encryption_mode确定,默认参数为 aes-128-cbc ),建议用户使用128bit/192bit/256bit的安全随机数作为密钥字符串。

-- init_vector:为需要它的块解密模式提供初始化变量,长度大于等于16字节(大于16的字节会被在自动忽略)。pass_str和key_str均不为NULL时,该参数不可为NULL,否则报错。为了安全,建议用户在OFB模式下,保证每次加密IV值的唯一性;在CBC模式和CFB模式下,保证每次加密的IV值不可被预测。

返回值类型:text

aes-128-cbc 加解密对应的java代码

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Base64;

/**
 * 测试 AES-128-CBC 加解密 (base64、hex)
 */
public class Aes128CbcEncryptForGBaseDemo {

    /**
     * 加密
     * select hex(aes_encrypt('hello,world_hex', 'GBase8c123456789','1234567890123456')) from dual;
     * select to_base64(aes_encrypt('hello,world_base64', 'GBase8c123456789','1234567890123456')) from dual;
     * 解密
     * select aes_decrypt(TRIM(unhex(data)),'GBase8c123456789', '1234567890123456') AS decrypted_data FROM encrypted_data_hex;
     * select aes_decrypt(TRIM(from_base64(data)),'GBase8c123456789', '1234567890123456') AS decrypted_data FROM encrypted_data_base64;
     *
     * CREATE TABLE encrypted_data_hex (
     *     id SERIAL PRIMARY KEY,
     *     data TEXT
     * );
     * CREATE TABLE encrypted_data_base64 (
     *     id SERIAL PRIMARY KEY,
     *     data TEXT
     * );
     */
    private static String DB_URL = "jdbc:gbase://*.*.*.*:15400/gbase?currentSchema=t_encrypted";
    private static String DB_USER = "gbase8c";
    private static String DB_PASSWORD = "Password@123";
    // AES加密密钥
    private static String KEY = "GBase8c123456789";
    // AES加密向量
    private static String IV = "1234567890123456";

    // 使用Base64进行加密
    public static String encryptToBase64(String data, String key, String iv) throws Exception {
        try {
            // 创建AES加密器
            Cipher cipher = Cipher.getInstance("AES/CBC/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));

            // 将加密结果转换为Base64字符串并返回
            return base64Encode(encrypted);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 使用Base64进行解密
    public static String desEncryptFromBase64(String data, String key, String iv) throws Exception {
        try {
            // 将Base64字符串解码为字节数组
            byte[] encrypted = base64Decode(data);

            // 创建AES解密器
            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(encrypted);

            // 将解密结果转换为字符串并返回
            return new String(original, StandardCharsets.UTF_8).trim();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 使用16进制进行加密
    public static String encryptToHex(String data, String key, String iv) throws Exception {
        try {
            // 创建AES加密器
            Cipher cipher = Cipher.getInstance("AES/CBC/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));

            // 将加密结果转换为16进制字符串并返回
            return bytesToHex(encrypted);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 使用16进制进行解密
    public static String desEncryptFromHex(String data, String key, String iv) throws Exception {
        try {
            // 将16进制字符串转换为字节数组
            byte[] encrypted = hexStringToByteArray(data);

            // 创建AES解密器
            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(encrypted);

            // 将解密结果转换为字符串并返回
            return new String(original, StandardCharsets.UTF_8).trim();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 将字节数组转换为16进制字符串
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }

    // 将16进制字符串转换为字节数组
    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }

    // 使用Base64进行编码
    public static String base64Encode(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }

    // 使用Base64进行解码
    public static byte[] base64Decode(String str) {
        return Base64.getDecoder().decode(str);
    }

    public static void storeBase64EncryptedData(String data) {
        try {
            Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            String encryptedData = encryptToBase64(data, KEY, IV);

            String query = "INSERT INTO encrypted_data_base64(data) VALUES(?)";
            PreparedStatement statement = conn.prepareStatement(query);
            statement.setString(1, encryptedData);

            statement.executeUpdate();

            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String retrieveBase64DecryptedData() {
        String decryptedData = null;
        try {
            Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            String query = "SELECT data FROM encrypted_data_base64";
            PreparedStatement statement = conn.prepareStatement(query);
            ResultSet resultSet = statement.executeQuery();

            if (resultSet.next()) {
                String encryptedData = resultSet.getString("data");
                decryptedData = desEncryptFromBase64(encryptedData, KEY, IV);
            }

            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return decryptedData;
    }

    public static void storeHexEncryptedData(String data) {
        try {
            Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            String encryptedData = encryptToHex(data, KEY, IV);

            String query = "INSERT INTO encrypted_data_hex(data) VALUES(?)";
            PreparedStatement statement = conn.prepareStatement(query);
            statement.setString(1, encryptedData);

            statement.executeUpdate();

            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String retrieveHexDecryptedData() {
        String decryptedData = null;
        try {
            Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            String query = "SELECT data FROM encrypted_data_hex";
            PreparedStatement statement = conn.prepareStatement(query);
            ResultSet resultSet = statement.executeQuery();

            if (resultSet.next()) {
                String encryptedData = resultSet.getString("data");
                decryptedData = desEncryptFromHex(encryptedData, KEY, IV);
            }

            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return decryptedData;
    }

    public static void main(String[] args) throws Exception {
        String data_hex = "hello,world_hex";
        storeHexEncryptedData(data_hex);
        String decryptedHexData = retrieveHexDecryptedData();
        System.out.println("Decrypted Hex Data: " + decryptedHexData);

        String data_base64 = "hello,world_base64";
        storeBase64EncryptedData(data_base64);
        String decryptedBase64Data = retrieveBase64DecryptedData();
        System.out.println("Decrypted Base64 Data: " + decryptedBase64Data);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值