mysql java 通用AES加密
最近有个需求,需要对数据库某些字段加密,调研发现采用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("加密秘钥失败");
} }
}
mysql java 通用AES加密的更多相关文章
- php与java通用AES加密解密算法
AES指高级加密标准(Advanced Encryption Standard),是当前最流行的一种密码算法,在web应用开发,特别是对外提供接口时经常会用到,下面是我整理的一套php与java通用的 ...
- java使用AES加密解密 AES-128-ECB加密
java使用AES加密解密 AES-128-ECB加密 import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; impo ...
- Java实现AES加密,异常java.security.InvalidKeyException: Illegal key size 的解决
Java实现AES加密,抛出异常如下:java.security.InvalidKeyException: Illegal key size 代码参考 http://my.oschina.net/Ja ...
- Java实现AES加密(window机器和linux机器) 注意window机器 和linux机器算法稍有不同
一)什么是AES? 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用. ...
- [Java 实现AES加密解密]
今天同学请教我这个问题,被坑了次…… 实现的功能是2个Java类:一个读取源文件生成加密文件,另一个类读取加密文件来解密. 整个过程其实很简单,java有AES的工具包,设好秘钥,设好输入内容,就得到 ...
- iOS与Android通用AES加密
找了很久才成功的aes 加密 服务器java写的 下载地址 https://pan.baidu.com/s/1nvi1zjr
- Java实现AES加密
一)什么是AES? 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用. ...
- 使用java进行 AES 加密 解密?
百度百科是这样定义的: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标 ...
- Java使用AES加密解密
AES加密机制: 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准. 这个标准用来替代原先的 ...
随机推荐
- docker常用命令行集锦
对工作中用到的docker命令行进行一个汇总,方便以后的命令行查询,同时也为了加强记忆,会把工作中用到的命令,持续更新上 1.查看私有仓库都有哪些镜像 curl -X GET http://10.27 ...
- 网络通讯与IP地址
1.主机:Host,台式机,笔记本,手机等设备 2.网络介质:网线,光纤,无线网Wi-Fi.移动网络 3.数据:一串子节 网络通讯的检测:安装wireshark,通常称为抓包工具 抓,capture ...
- node mysql问题:Client does not support authentication protocol requested by server; consider upgrading MySQL client!
node后台 mysql处理模块(版本:2.16.0) 执行connect方法时报错: Client does not support authentication protocol requeste ...
- (转)Selenium-11: Execute JavaScript with JavascriptExecutor
Outline Sometimes we cannot handle some conditions or problems with Webdriver, web controls don’t re ...
- java经典学习路线
恩,做开发的工作已经三年多了,说起来实在是惭愧,自己的知识树还像一棵小草一样,工作中使用到了许多的知识和技术,不过系统性不够.根基不牢.并且不够深入!当然,慢慢的我也更加的清楚,我需要学习一些什么样的 ...
- FlowLayout(流式布局)用法
https://blog.csdn.net/liujun13579/article/details/7771191
- redis常用数据类型与命令
注意:LPUSH 和LPOP按照栈进行操作,RPUSH和RPOP按照队列进行操作 zremrangebyscore key score开始 score结束//根据score删除 zremrangeb ...
- Luogu P4095 [HEOI2013]Eden 的新背包问题 思维/动规
当时一直在想前缀和...多亏张队提醒... 从1到n背次包,保存每一个状态下的价值,就是不要把第一维压掉:再从n到1背一次,同样记住每种状态: 然后询问时相当于是max(前缀+后缀),当然前缀后缀中间 ...
- 1001 害死人不偿命的(3n+1)猜想 (15)(15 分)
卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到n=1.卡拉兹在1950年的世界数 ...
- poj3713 Transferring Sylla 枚举+tarjan判割点
其实就是判断是否为三连通图 三连通图指的是去掉3个点就不连通的图,但是并没有直接求三连通的算法.著名的Tarjan算法可以求解连通和割点,再枚举删除一个点就能达到三连通的目的. 先看用例2,是由用例1 ...