java使用AES加密数据库解密

发布时间:2024年01月20日

前言

在一些项目中,客户要求一方面把一些敏感信息进行加密存储到数据库中,另一方面又需要通过加密的信息进行查询,这时就需要在sql对加密的字段进行解密后再进行查询。

代码加密(AES)

AesFieldUtils.java

package com.hw.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


@Slf4j
public class AesFieldUtils {
    /**
     * 加密算法
     */
    private final String KEY_ALGORITHM = "AES";
    /**
     * 算法/模式/补码方式
     */
    private final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    /**
     * 编码格式
     */
    private final String CODE = "utf-8";
    /**
     * base64验证规则
     */
    private static final String BASE64_RULE = "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)=?$";
    /**
     * 正则验证对象
     */
    private static final Pattern PATTERN = Pattern.compile(BASE64_RULE);
    /**
     * 加解密 密钥key
     */
    private String key


    /**
     * @param content 加密字符串
     * @return 加密结果
     */
    public String encrypt(String content) {
        return encrypt(content, key);
    }

    /**
     * 加密
     *
     * @param content 加密参数
     * @param key     加密key
     * @return 结果字符串
     */
    public String encrypt(String content, String key) {
        //判断如果已经是base64加密字符串则返回原字符串
        if (isBase64(content)) {
            return content;
        }
        // 为了安全起见,暂时不加密,需要时再放开
        //return content;
         byte[] encrypted = encrypt2bytes(content, key);
        if (null == encrypted || encrypted.length < 1) {
            log.error("加密字符串[{}]转字节为null", content);
            return null;
        }
        return Base64Utils.encodeToString(encrypted);

    }

    /**
     * @param content 加密字符串
     * @param key     加密key
     * @return 返回加密字节
     */
    public byte[] encrypt2bytes(String content, String key) {
        try {
            byte[] raw = key.getBytes(CODE);
            SecretKeySpec secretKeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            return cipher.doFinal(content.getBytes(CODE));
        } catch (Exception e) {
            log.error("failed to encrypt: {} of {}", content, e);
            return null;
        }
    }

    /**
     * @param content 加密字符串
     * @return 返回加密结果
     */
    public String decrypt(String content) {
        try {
            return decrypt(content, key);
        } catch (Exception e) {
            log.error("failed to decrypt: {}, e: {}", content, e);
            return null;
        }
    }

    /**
     * 解密
     *
     * @param content 解密字符串
     * @param key     解密key
     * @return 解密结果
     */
    public String decrypt(String content, String key) throws Exception {
        //不是base64格式字符串则不进行解密
        if (!isBase64(content)) {
            return content;
        }
        // 为了安全起见,暂时不加密解密,需要时再放开
        //return content;
        return decrypt(Base64Utils.decodeFromString(content), key);
    }

    /**
     * @param content 解密字节
     * @param key     解密key
     * @return 返回解密内容
     */
    public String decrypt(byte[] content, String key) throws Exception {
        if (key == null) {
            log.error("AES key should not be null");
            return null;
        }

        byte[] raw = key.getBytes(CODE);
        SecretKeySpec keySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, keySpec);
        try {
            byte[] original = cipher.doFinal(content);
            return new String(original, CODE);
        } catch (Exception e) {
            log.error("failed to decrypt content: {}/ key: {}, e: {}", content, key, e);
            return null;
        }
    }

    /**
     * 判断是否为 base64加密
     *
     * @param str 参数
     * @return 结果
     */
    public static boolean isBase64(String str) {
        Matcher matcher = PATTERN.matcher(str);
        return matcher.matches();
    }

    public static void main(String[] args) {
       AesFieldUtils aesFieldUtils = new AesFieldUtils();
        String reuslt = aesFieldUtils.encrypt("13809449025","qwertyuiopasdfgh");
        System.out.println(reuslt);
    }


}

加密的密文:dcAJ143U+AkxbvOwRctnVg==
在这里插入图片描述

sql解密

mysql 使用 AES_DECRYPT(crypt_str,key_str) 进行解密,第一个参数crypt_str加密的字符串,第二个参数key_str 密钥,需和代码加密时的密钥保持一致。

SELECT 
	AES_DECRYPT(FROM_BASE64('dcAJ143U+AkxbvOwRctnVg=='), 'qwertyuiopasdfgh') AS '解密结果';

在这里插入图片描述

文章来源:https://blog.csdn.net/liqinglonguo/article/details/135702284
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。