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>
已下载:478 次
原创文章,转载请注明出处:https://www.weizhixi.com/article/38.html