ASE算法 hivejava加密解密算法后怎么在java中解密

JAVA实现AES加密
JAVA实现AES加密
上次介绍了》,中间提到近些年DES使用越来越少,原因就在于其使用56位密钥,比较容易被破解,近些年来逐渐被AES替代,AES已经变成目前对称加密中最流行算法之一;AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据。本文就简单介绍如何通过JAVA实现AES加密。
2. JAVA实现
闲话少许,掠过AES加密原理及算法,关于这些直接搜索专业网站吧,我们直接看JAVA的具体实现。
代码有详细解释,不多废话。
* @param content 需要加密的内容
* @param password
public static byte[] encrypt(String content, String password) {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
代码有详细注释,不多废话
注意:解密的时候要传入byte数组
* @param content
待解密内容
* @param password 解密密钥
public static byte[] decrypt(byte[] content, String password) {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
2.3 测试代码
String content = "test";
String password = "";
System.out.println("加密前:" + content);
byte[] encryptResult = encrypt(content, password);
byte[] decryptResult = decrypt(encryptResult,password);
System.out.println("解密后:" + new String(decryptResult));
输出结果如下:
加密前:test解密后:test
2.4 容易出错的地方
但是如果我们将测试代码修改一下,如下:
String content = "test";
String password = "";
System.out.println("加密前:" + content);
byte[] encryptResult = encrypt(content, password);
String encryptResultStr = new String(encryptResult,"utf-8");
byte[] decryptResult = decrypt(encryptResultStr.getBytes("utf-8"),password);
System.out.println("解密后:" + new String(decryptResult));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
则,系统会报出如下异常:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
这主要是因为加密后的byte数组是不能强制转换成字符串的,换言之:字符串和byte数组在这种情况下不是互逆的;要避免这种情况,我们需要做一些修订,可以考虑将二进制数据转换成十六进制表示,主要有如下两个方法:
2.4.1将二进制转换成16进制
/**将二进制转换成16进制
* @param buf
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i & buf. i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' +
sb.append(hex.toUpperCase());
return sb.toString();
2.4.2 将16进制转换为二进制
/**将16进制转换为二进制
* @param hexStr
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() & 1)
byte[] result = new byte[hexStr.length()/2];
for (int i = 0;i& hexStr.length()/2; i++) {
int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
result[i] = (byte) (high * 16 + low);
然后,我们再修订以上测试代码,如下:
String content = "test";
String password = "";
System.out.println("加密前:" + content);
byte[] encryptResult = encrypt(content, password);
String encryptResultStr = parseByte2HexStr(encryptResult);
System.out.println("加密后:" + encryptResultStr);
byte[] decryptFrom = parseHexStr2Byte(encryptResultStr);
byte[] decryptResult = decrypt(decryptFrom,password);
System.out.println("解密后:" + new String(decryptResult));
测试结果如下:
加密前:test加密后:73C58BAFE578CCD0B9D6D解密后:test
2.5 另外一种加密方式
还有一种加密方式,大家可以参考如下:
* @param content 需要加密的内容
* @param password
public static byte[] encrypt2(String content, String password) {
SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
这种加密方式有两种限制
密钥必须是16位的
待加密内容的长度必须是16的倍数,如果不是16的倍数,就会出如下异常:
javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
at com.sun.crypto.provider.SunJCE_f.a(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
要解决如上异常,可以通过补全传入加密内容等方式进行避免。
帮朋友宣传:
依赖淘宝TOP平台的API,封装了多种酷炫组件,面向广大淘客提供免费建站推广功能,目前已经入住淘宝箱,正式对外运营,欢迎各位围观。
没有更多推荐了,
不良信息举报
举报内容:
JAVA实现AES加密
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!AES加解密算法,代码如下:
* Created by hua on .
import javax.crypto.C
import javax.crypto.spec.IvParameterS
import javax.crypto.spec.SecretKeyS
public class AESUtil1 {
//初始化向量,aes 16位
private static final String IV = "abcdefghijk1mnop";
//二进制转变为16进制
public static String parseByte2HexStr(byte[] buf) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i & buf. i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' +
sb.append(hex);
return sb.toString();
//将16进制转变为二进制
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() & 1) {
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i & hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
public static String encrypt(String content, String keyWord) throws Exception {
SecretKeySpec key = new SecretKeySpec(keyWord.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV.getBytes()));
byte[] encryptedData = cipher.doFinal(content.getBytes("UTF-8"));
return parseByte2HexStr(encryptedData);
} catch (Exception e) {
throw new Exception("加密失败");
public static String decrypt(String content, String keyWord) throws Exception {
byte[] contentBytes = parseHexStr2Byte(content);
SecretKeySpec key = new SecretKeySpec(keyWord.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV.getBytes()));
byte[] result = cipher.doFinal(contentBytes);
return new String(result, "UTF-8");
} catch (Exception e) {
throw new Exception("解密失败");
public static void main(String[] args) throws Exception {
String content = "梅须逊雪三分白,雪却输梅一段香。";
String password = "abcdef";
//此处使用AES-128-CBC加密模式,key需要为16位
System.out.println("加密前:" + content);
String encryptResult = AESUtil1.encrypt(content, password);
System.out.println("加密后:" + encryptResult);
String decryptResult = AESUtil1.decrypt(encryptResult,password);
System.out.println("解密后:" + decryptResult);
运行输出如下:
加密前:梅须逊雪三分白,雪却输梅一段香。
加密后:a955f0febe61b9bceb383d608c1ba2da97fe0d6500d1dac786aa69e593a67a23c5ee8fd
解密后:梅须逊雪三分白,雪却输梅一段香。
阅读(...) 评论()博客分类:
Java 加密解密之对称加密算法AES
密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于日发布于FIPS PUB 197,并在日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael之命名之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 "Rhinedoll"。)
AES是美国国家标准技术研究所NIST旨在取代DES的21世纪的加密标准。
AES的基本要求是,采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。1998年NIST开始AES第一轮分析、测试和征集,共产生了15个候选算法。1999年3月完成了第二轮AES2的分析、测试。日美国政府正式宣布选中比利时密码学家Joan Daemen 和 Vincent Rijmen 提出的一种密码算法RIJNDAEL 作为 AES.   在应用方面,尽管DES在安全上是脆弱的,但由于快速DES芯片的大量生产,使得DES仍能暂时继续使用,为提高安全强度,通常使用独立密钥的三级DES。但是DES迟早要被AES代替。流密码体制较之分组密码在理论上成熟且安全,但未被列入下一代加密标准。   AES加密数据块和密钥长度可以是128比特、192比特、256比特中的任意一个。
AES加密有很多轮的重复和变换。大致步骤如下:
1、密钥扩展(KeyExpansion),
2、初始轮(Initial Round),
3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,
4、最终轮(Final Round),最终轮没有MixColumns。
JDK对DESede算法的支持
密钥长度:128位工作模式:ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128填充方式:Nopadding/PKCS5Padding/ISO10126Padding/
工作模式和填充方式请参考:
十六进制工具类Hex.java,见:
AES加密解密的java实现:AESCoder.java
import java.security.K
import java.security.NoSuchAlgorithmE
import javax.crypto.C
import javax.crypto.KeyG
import javax.crypto.SecretK
import javax.crypto.spec.SecretKeyS
* AES Coder&br/&
* secret key length: 128bit, default: 128 bit&br/&
* mode: ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128&br/&
* padding: Nopadding/PKCS5Padding/ISO10126Padding/
* @author Aub
public class AESCoder {
* 密钥算法
private static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
* 初始化密钥
* @return byte[] 密钥
* @throws Exception
public static byte[] initSecretKey() {
//返回生成指定算法的秘密密钥的 KeyGenerator 对象
KeyGenerator kg =
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return new byte[0];
//初始化此密钥生成器,使其具有确定的密钥大小
//AES 要求密钥长度为 128
kg.init(128);
//生成一个密钥
secretKey = kg.generateKey();
return secretKey.getEncoded();
* 转换密钥
* @param key 二进制密钥
* @return 密钥
private static Key toKey(byte[] key){
//生成密钥
return new SecretKeySpec(key, KEY_ALGORITHM);
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
* @throws Exception
public static byte[] encrypt(byte[] data,Key key) throws Exception{
return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
* @param data 待加密数据
* @param key 二进制密钥
* @return byte[] 加密数据
* @throws Exception
public static byte[] encrypt(byte[] data,byte[] key) throws Exception{
return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
* @param data 待加密数据
* @param key 二进制密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 加密数据
* @throws Exception
public static byte[] encrypt(byte[] data,byte[] key,String cipherAlgorithm) throws Exception{
//还原密钥
Key k = toKey(key);
return encrypt(data, k, cipherAlgorithm);
* @param data 待加密数据
* @param key 密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 加密数据
* @throws Exception
public static byte[] encrypt(byte[] data,Key key,String cipherAlgorithm) throws Exception{
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
//使用密钥初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, key);
//执行操作
return cipher.doFinal(data);
* @param data 待解密数据
* @param key 二进制密钥
* @return byte[] 解密数据
* @throws Exception
public static byte[] decrypt(byte[] data,byte[] key) throws Exception{
return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密数据
* @throws Exception
public static byte[] decrypt(byte[] data,Key key) throws Exception{
return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
* @param data 待解密数据
* @param key 二进制密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 解密数据
* @throws Exception
public static byte[] decrypt(byte[] data,byte[] key,String cipherAlgorithm) throws Exception{
//还原密钥
Key k = toKey(key);
return decrypt(data, k, cipherAlgorithm);
* @param data 待解密数据
* @param key 密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 解密数据
* @throws Exception
public static byte[] decrypt(byte[] data,Key key,String cipherAlgorithm) throws Exception{
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
//使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, key);
//执行操作
return cipher.doFinal(data);
private static String
showByteArray(byte[] data){
if(null == data){
StringBuilder sb = new StringBuilder("{");
for(byte b:data){
sb.append(b).append(",");
sb.deleteCharAt(sb.length()-1);
sb.append("}");
return sb.toString();
public static void main(String[] args) throws Exception {
byte[] key = initSecretKey();
System.out.println("key:"+showByteArray(key));
Key k = toKey(key);
String data ="AES数据";
System.out.println("加密前数据: string:"+data);
System.out.println("加密前数据: byte[]:"+showByteArray(data.getBytes()));
System.out.println();
byte[] encryptData = encrypt(data.getBytes(), k);
System.out.println("加密后数据: byte[]:"+showByteArray(encryptData));
System.out.println("加密后数据: hexStr:"+Hex.encodeHexStr(encryptData));
System.out.println();
byte[] decryptData = decrypt(encryptData, k);
System.out.println("解密后数据: byte[]:"+showByteArray(decryptData));
System.out.println("解密后数据: string:"+new String(decryptData));
参考《java加密与解密的艺术》
浏览 29974
冲杯茶喝 写道//实例化& &&&&&&& Cipher cipher = Cipher.getInstance(cipherAlgorithm);& &&&&&&& //使用密钥初始化,设置为解密模式& &&&&&&& cipher.init(Cipher.DECRYPT_MODE, key);& Cipher对象可否复用??我之前测试时 是可以服用的 建议你再测测复用我测试过可以,但是不是线程安全的呢
//实例化& &&&&&&& Cipher cipher = Cipher.getInstance(cipherAlgorithm);& &&&&&&& //使用密钥初始化,设置为解密模式& &&&&&&& cipher.init(Cipher.DECRYPT_MODE, key);& Cipher对象可否复用??我之前测试时 是可以服用的 建议你再测测
java是不是原生并不支持pkcs7?Exception in thread "main" java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS7Padding对,java原生的jdk中目前还不支持pkcs7,你可以使用第三方的实现
浏览: 475956 次
来自: 北京
你好,你这个写错了,容量的单位不是字节,是KB。[http:/ ...
太感谢了,感谢分享!
为什么换成CBC或者其他的模式后解码会报java.securi ...
楼主,我如何设置 只显示insert 和update、dele ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 java rsa加密解密算法 的文章

 

随机推荐