mysql java 通用AES加密

本文探讨了在MySQL中采用AES加密技术对特定字段进行加密的过程,对比了HEX与Base64编码方式对数据长度的影响,并分享了在处理历史数据时的实践技巧。

最近有个需求,需要对数据库某些字段加密,调研发现采用AES加密的方式较多,而且反向解密速度快,符合需求,于是采用;下面是遇到的问题及相关代码

首先第一个问题,AES的秘钥是16位,mysql的密码长度aes_encrypt没有要求:

  是因为mysql默认取秘钥的ascii编码前16位,相当于:

  byte[] keyBytes = Arrays.copyOf(password.getBytes("ASCII"), 16);

 

第二个问题,因涉及历史数据处理,mysql需要使用aes_encrypt加密:

但是生成的二进制数据,要把二进制数据存到原先的varchar字段中,网上搜索多数采用的HEX(aes_encrypt(name, "password")),而HEX编码会过分增大原数据的长度(据说是增倍),有的字段长度会变的过长;

于是再查询发现,mysql5.6以后增加了to_base64的base64编码方式。两者区别

  • hex也称为base16,意思是使用16个可见字符来表示一个二进制数组,编码后数据大小将翻倍,因为1个字符需要用2个可见字符来表示。

  • base32,意思是使用32个可见字符来表示一个二进制数组,编码后数据大小变成原来的8/5,也即5个字符用8个可见字符表示,但是最后如果不足8个字符,将用=来补充。

  • base64,意思是使用64个可见字符来表示一个二进制数组,编码后数据大小变成原来的4/3,也即3个字符用4个可见字符来表示。

可见base64的字段长度比HEX少很多,db设计不是很严谨的甚至不必增加字段长度;

相关sql:

加密

update T_USER t
set t.name=to_base64(aes_encrypt(name, "password"));

解密

select cast(aes_decrypt(from_base64(name) ,"password") as char) from T_USER;

java类:

import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;
import java.util.Base64;

/**
* Created by Administrator on 2018/11/8.
*/
public class EncryptUtil {
private static final String PASS_WORD="edmund2018";
private static SecretKeySpec AES_PASSWORD;
private static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法

/**
* AES 加密操作
*
* @param content 待加密内容
* @return 返回Base64转码后的加密数据
*/
public static String encrypt(String content) {
if(StringUtils.isEmpty(content)) {
return content;
}
try {
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(PASS_WORD));// 初始化为加密模式的密码器

byte[] encrypted = cipher.doFinal(content.getBytes("utf-8"));

return new BASE64Encoder().encode(encrypted);
} catch (Exception ex) {
Logger.defalutLogger.error("加密失败");
}

return content;
}

/**
* AES 解密操作
*
* @param content
* @return
*/
public static String decrypt(String content) {
if(StringUtils.isEmpty(content)) {
return content;
}
try {
//实例化
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);

//使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(PASS_WORD));
byte[] base64Data = new BASE64Decoder().decodeBuffer(content);//先用base64解密
byte[] original = cipher.doFinal(base64Data);
String originalString = new String(original,"utf-8");
return originalString;
} catch (Exception ex) {
Logger.defalutLogger.error("解密失败"+ex.getStackTrace());
}
return content;
}

/**
* 生成加密秘钥
*
* @return
*/
private static SecretKeySpec getSecretKey(final String password) throws Exception {
if(AES_PASSWORD !=null){
return AES_PASSWORD;
}
try { //返回生成指定算法密钥生成器的 KeyGenerator 对象
byte[] keyBytes = Arrays.copyOf(password.getBytes("ASCII"), 16);
AES_PASSWORD =new SecretKeySpec(keyBytes, KEY_ALGORITHM);// 转换为AES专用密钥
return AES_PASSWORD;
} catch (Exception ex) {
Logger.defalutLogger.error("加密秘钥失败"+ex.getStackTrace());
throw new Exception("加密秘钥失败");
}

}
}

 

转载于:https://www.cnblogs.com/binlin1987/p/9933998.html

<think>嗯,用户这次想了解数据库字段加密的工具或软件。从引用内容看,用户之前已经研究过TDE透明数据加密和SpringBoot的参数加密方案,现在需要更具体的工具推荐。用户可能是在做数据库安全方案选型,或是需要满足合规要求(比如GDPR或等保)。ta的提问很精准,说明有一定技术基础,但可能对商用产品和开源工具的区别不太清楚。我注意到ta两次都提到"字段级加密",说明应用场景需要细粒度控制,而非全盘加密。需要区分几个层面:首先是基础技术方案(TDE、列加密、应用层加密),然后是具体实现工具。Vormetric和AWSKMS适合企业级需求,开源方案如cryptdb则更灵活但需要自维护。特别要提醒Java生态用户,如果已用SpringBoot,可以直接集成jasypt避免重复造轮子。风险提示很重要:密钥管理比加密算法本身更关键,这点用户可能容易忽略。另外要强调性能影响——加密字段的索引问题在引用[1]中提到过,但用户似乎没意识到这会影响查询效率。最后生成的补充问题要引导用户深入:密钥管理方案和选型因素是实际实施时必然遇到的坎,而性能测试问题则能帮ta预判落地风险。用户没提预算,所以商业工具和开源方案都要覆盖。</think> 针对数据库字段级别的加密需求,以下是根据不同场景推荐的核心工具和方案,涵盖商用产品和开源实现: ### 一、数据库原生解决方案 1. **透明数据加密 (TDE)** - **支持数据库**:Oracle Advanced Security TDE[^1], SQL Server TDE, MySQL Enterprise TDE - **原理**:实时加密数据和日志文件,通过数据库加密密钥(DEK)实现,DEK由主密钥或硬件模块保护 - **特点**:无需修改应用代码,但仅防护静态数据 2. **列级加密 (CLE)** - **MySQL示例**: ```sql CREATE TABLE users ( id INT PRIMARY KEY, phone VARBINARY(160) /* AES_ENCRYPT('数据','密钥') */ ); ``` - **SQL Server**:使用`Always Encrypted`技术,结合列主密钥(CMK)和数据加密密钥(DEK) ### 二、应用层加密工具 1. **Java生态** - **Jasypt**:集成Spring Boot的字段加密 ```java @EncryptParam // 自定义注解实现字段加密[^2] private String bankCardNo; ``` - **加密处理器示例**: ```java @Override public String convertToDatabaseColumn(String attribute) { return AES.encrypt(attribute, secretKey); // 入库加密 } ``` 2. **通用库** - **Google Tink**:提供安全API(如`Aead.encrypt()`),支持Java/Python/Go - **PyCryptodome**:Python开发者适用的AES/CBC-PKCS7实现 ### 三、企业级加密系统 1. **数据安全平台** - **Vormetric Data Security Platform**:实现字段/文件/大数据加密,支持集中密钥管理 - **Azure SQL Database**:结合Always Encrypted + Azure Key Vault 2. **云服务方案** - **AWS KMS + DynamoDB**:通过加密上下文(EncryptionContext)实现字段级保护 - **Google Cloud KMS + Spanner**:使用TINK加密库进行客户端加密 ### 四、搜索优化方案 **加密字段模糊查询需求** 1. **CryptDB**(MIT开源) - 支持同态加密,实现`WHERE state='CA'`类查询 - 分层密钥架构:`OPE`(保序加密), `DET`(确定性加密) 2. **CipherCloud**:商用方案,通过代理网关实现加密搜索 > **关键决策因素** > - 合规要求:金融场景优先选FIPS 140-2认证产品 > - 性能影响:TDE加密可导致5-15%性能损耗 > - 密钥管理:避免硬编码密钥(推荐HSM或云KMS方案) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值