zoukankan      html  css  js  c++  java
  • 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("加密秘钥失败");
    }

    }
    }
  • 相关阅读:
    想算法无头绪,咋办?
    使用R语言分析股价波动
    cmd控制台 wrapper | OpenSCManager failed
    Ubuntu使用vi命令时,不能正常编辑文件,使用方向键时老是出现很多字母解决方案
    Ubuntu su命令 Authentication failure的解决办法
    Springboot2.x整合RabbitMQ
    RabbitMQ 笔记
    Ubuntu安装RabbitMQ
    使用xshell连接ubuntu
    Java 泛型
  • 原文地址:https://www.cnblogs.com/binlin1987/p/9933998.html
Copyright © 2011-2022 走看看