java可逆AES加密工具类

知兮丶青 工具类 · 加密 · 解密
阅读(1944) 2017-12-21
java可逆AES加密工具类
java可逆AES加密工具类

java加密解密AES工具类。

有时会用到可逆加密工具类,个人认为AES还是很好用的,也比较流行。


简介

这个类提供了用于加密和解密的功能。这个类是Java加密扩展(JCE)框架的核心。

创可以通过调用Cipher类中的getInstance静态工厂方法得到Cipher对象。


可以有以下2中转型的形式:

algorithm/mode/padding 算法/模式/补码方式

algorithm 算法


下面的例子就是有效的转换形式为:

AES/CBC/NoPadding (128)

AES/CBC/PKCS5Padding (128)

AES/ECB/NoPadding (128)

AES/ECB/PKCS5Padding (128)

...

等等


AES加密解密

package com.weizhixi.util;
 
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;

/**
 * AES可逆加密
 * AES-128-CBC加密模式
 * Created by cxq on 2016/7/28.
 */
public class AES {
 
    /** 默认密钥,可以自定义*/
    private static final String KEY = "123@abc!";
    /** 向量密钥,可以自定义,必须128位(16字节) */
    private static final String PARAM_KEY ="1234561234567890";
    /** 转型形式 */
    private static final String CIPHER_KEY = "AES/CBC/PKCS5Padding";
    /** 编码 */
    private static final String CHARSET = "utf-8";
    /** 算法名 */
    public static final String MODE_AES = "AES";
 
    /**
     * 加密
     * @param sSrc 内容
     * @return
     */
    public static String encrypt(String sSrc){
        return encrypt(sSrc, KEY);
    }
 
    /**
     * 加密
     * @param sSrc 内容
     * @param sKey 密钥
     * @return
     */
    public static String encrypt(String sSrc, String sKey) {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER_KEY);//创建加密Cipher类实例
            KeyGenerator kgen = KeyGenerator.getInstance(MODE_AES);//AES加密密钥生成器
            kgen.init(128, new SecureRandom(sKey.getBytes(CHARSET)));//生成密钥128位(16字节)
            SecretKey secretKey = kgen.generateKey();//生成密钥
            IvParameterSpec iv = new IvParameterSpec(PARAM_KEY.getBytes(CHARSET));//向量iv
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);//加密初始化
            byte[] encrypted = cipher.doFinal(sSrc.getBytes(CHARSET));//完成加密操作
            return Base64.encodeBase64String(encrypted);
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }
 
    /**
     * 解密
     * @param sSrc 内容
     * @return
     */
    public static String decrypt(String sSrc){
        return decrypt(sSrc, KEY);
    }
 
    /**
     * 解密
     * @param sSrc 内容
     * @param sKey 密钥
     * @return
     */
    public static String decrypt(String sSrc, String sKey) {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER_KEY);//创建加密Cipher类实例
            KeyGenerator kgen = KeyGenerator.getInstance(MODE_AES);//AES加密密钥生成器
            kgen.init(128, new SecureRandom(sKey.getBytes(CHARSET)));//生成密钥128位(16字节)
            SecretKey secretKey = kgen.generateKey();//生成密钥
            IvParameterSpec iv = new IvParameterSpec(PARAM_KEY.getBytes(CHARSET));//向量iv
            cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);//解密初始化
            byte[] original = cipher.doFinal(Base64.decodeBase64(sSrc));//完成解密操作
            return new String(original);
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }
 
}


演示用法

默认密钥加密

String auth = encrypt("微知兮");
System.out.println("加密:"+auth);
String param = decrypt(auth);
System.out.println("解密:"+param);
//加密:ZRUkY1ApqlCmIYmKqM7qtw==
//解密:微知兮

自定义密钥解密,注意了16位

String auth = encrypt("微知兮", "weizhixi.com");
System.out.println("加密:"+auth);
String param = decrypt(auth, "weizhixi.com");
System.out.println("解密:"+param);
//加密:fCrtv0qww6EdXZmItFPcjg==
//解密:微知兮



可能遇到

当密钥少于16位时:

java.security.InvalidKeyException: Invalid AES key length: 5 bytes
	at com.sun.crypto.provider.AESCipher.engineGetKeySize(AESCipher.java:372)
	at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1052)
	at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1023)
	at javax.crypto.Cipher.implInit(Cipher.java:790)
	at javax.crypto.Cipher.chooseProvider(Cipher.java:849)
	at javax.crypto.Cipher.init(Cipher.java:1348)
	at javax.crypto.Cipher.init(Cipher.java:1282)
	at com.weizhixi.util.AES.encrypt(AES.java:47)
	at com.weizhixi.util.AES.main(AES.java:94)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
java.security.InvalidKeyException: Invalid AES key length: 5 bytes
	at com.sun.crypto.provider.AESCipher.engineGetKeySize(AESCipher.java:372)
	at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1052)
	at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1023)
	at javax.crypto.Cipher.implInit(Cipher.java:790)
	at javax.crypto.Cipher.chooseProvider(Cipher.java:849)
	at javax.crypto.Cipher.init(Cipher.java:1348)
	at javax.crypto.Cipher.init(Cipher.java:1282)
	at com.weizhixi.util.AES.decrypt(AES.java:76)
	at com.weizhixi.util.AES.main(AES.java:96)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

当解解密错误时(注意加密解密密钥要一致,也可能受向量iv、字符编码方式等影响):

javax.crypto.BadPaddingException: Given final block not properly padded
	at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
	at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
	at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
	at javax.crypto.Cipher.doFinal(Cipher.java:2087)
	at com.weizhixi.util.AES.decrypt(AES.java:77)
	at com.weizhixi.util.AES.main(AES.java:96)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)


可能你需要导入 commons-codec.jar,或者是用你的Base64类或其他包Base64类。

maven引入:1.10版本

<dependency>
  <groupId>commons-codec</groupId>
  <artifactId>commons-codec</artifactId>
  <version>1.10</version>
</dependency>



zip icon
AES加密工具类.zip ee591b001f81b5f00d156e2509f29096

已下载:439

原创文章,转载请注明出处:https://www.weizhixi.com/article/38.html