最近有个需求,需要对数据库某些字段加密,调研发现采用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加密的更多相关文章

  1. php与java通用AES加密解密算法

    AES指高级加密标准(Advanced Encryption Standard),是当前最流行的一种密码算法,在web应用开发,特别是对外提供接口时经常会用到,下面是我整理的一套php与java通用的 ...

  2. java使用AES加密解密 AES-128-ECB加密

    java使用AES加密解密 AES-128-ECB加密 import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; impo ...

  3. Java实现AES加密,异常java.security.InvalidKeyException: Illegal key size 的解决

    Java实现AES加密,抛出异常如下:java.security.InvalidKeyException: Illegal key size 代码参考 http://my.oschina.net/Ja ...

  4. Java实现AES加密(window机器和linux机器) 注意window机器 和linux机器算法稍有不同

    一)什么是AES? 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用. ...

  5. [Java 实现AES加密解密]

    今天同学请教我这个问题,被坑了次…… 实现的功能是2个Java类:一个读取源文件生成加密文件,另一个类读取加密文件来解密. 整个过程其实很简单,java有AES的工具包,设好秘钥,设好输入内容,就得到 ...

  6. iOS与Android通用AES加密

    找了很久才成功的aes 加密  服务器java写的 下载地址 https://pan.baidu.com/s/1nvi1zjr

  7. Java实现AES加密

    一)什么是AES? 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用. ...

  8. 使用java进行 AES 加密 解密?

    百度百科是这样定义的: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标 ...

  9. Java使用AES加密解密

    AES加密机制: 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准. 这个标准用来替代原先的 ...

随机推荐

  1. UWP&WP8.1 基础控件——Border

    border 是边框控件 border是UWP和WP8.1最常用的控件之一. border字面意义是用来添加边框的. 基础用法 <border BorderThickness="1&q ...

  2. 读取word

    目标:将word中数据转存到数据库 实质:数据的读写 难点:word文件格式的处理(识别,读取),/ 提取word有效的相关字段 实现: 1.基础了解:word(文字处理应用程序/文档工具)软件   ...

  3. 写一个Android输入法02——候选窗、转换

    上一篇介绍了完成Android输入法的最小化步骤,它只能将按键对应的字符上屏.一般的东亚语言都有一个转换的过程,比如汉语输入拼音,需要由拼音转成汉字再上屏.本文将在前文基础上加入完成转换过程所必需的候 ...

  4. [SinGuLaRiTy] (树形)数据结构题目复习

    [SinGuLaRiTy-1023] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 普通平衡树 题目描述 你需要写一种数据结构(可参考题目标 ...

  5. kuangbin专题十六 KMP&&扩展KMP HDU1358 Period

    For each prefix of a given string S with N characters (each character has an ASCII code between 97 a ...

  6. eclipse字体

  7. 树莓派编译安装 EMQ 服务器

    前言 EMQ 是一款开源的物联网 MQTT 消息服务器,使用 Erlang/OTP 语言平台设计,在 DIY 智能家居时可以作为网关,前几天摸索了一下在树莓派中安装 EMQ 的方法,记录一下. 步骤 ...

  8. How to pass multiple parameters in PowerShell invoke-restmethod

    Link: http://www.tagwith.com/question_322855_how-to-pass-parameters-in-powershell-invoke-restmethod- ...

  9. 关于django的模板层

    你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. def current_datetime(request): now = datet ...

  10. CSS控制标题字符长度的方法

    <style type="text/css"> .abc { background-color: #CCC; width: auto; overflow:hidden; ...