AES已经变成目前对称加密中最流行算法之一;AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据。

    /**
* 加密
*
* @param content 需要加密的内容
* @param password 加密密码
* @return
*/
public static byte[] encrypt(String content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");    //创建AES的key生产者
kgen.init(128, new SecureRandom(password.getBytes()));  //利用用户密码作为随机码初始化 
        //使其具有确定的128个字节的密钥大小,SecureRandom是生成安全随机数序列,
        //password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行
SecretKey secretKey = kgen.generateKey();    //根据用户密码生成密钥
byte[] enCodeFormat = secretKey.getEncoded();  //返回基本编码格式的密钥,如果此密钥不支持编码,返回null
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");  //根据给定的字节数组构造一个为AES专用密钥
Cipher cipher = Cipher.getInstance("AES");    // 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);      // 初始化为加密模式
byte[] result = cipher.doFinal(byteContent);
return result; // 加密
} 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();
}
return null;
}

  

  

  

注意:解密的时候要传入byte数组

    /**解密
* @param content 待解密内容
* @param password 解密密钥
* @return
*/
public static byte[] decrypt(byte[] content, String password) {
try {
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);
return result;
} 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();
}
return null;
}

  

String content = "test";
String password = "12345678";
//加密
System.out.println("加密前:" + content);
byte[] encryptResult = encrypt(content, password);
//解密
byte[] decryptResult = decrypt(encryptResult,password);
System.out.println("解密后:" + new String(decryptResult));

  

输出结果如下:
加密前:test
解密后:test
 

容易出错的地方

但是如果我们将测试代码修改一下,如下:

 String content = "test";
String password = "12345678";
//加密
System.out.println("加密前:" + content);
byte[] encryptResult = encrypt(content, password);
try {
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数组在这种情况下不是互逆的;要避免这种情况,我们需要做一些修订,可以考虑将二进制数据转换成十六进制表示,主要有如下两个方
 
将二进制转换成16进制
**将二进制转换成16进制
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}

  

将16进制转换为二进制

/**将16进制转换为二进制
* @param hexStr
* @return
*/
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);
}
return result;
}

  

String content = "test";
String password = "12345678";
//加密
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
加密后:73C58BAFE578C59366D8C995CD0B9D6D
解密后:test

也可以使用BASE64进行包装处理。

加密bytes[] ----> passwordStr: new String(new BASE64Encoder().encode(doFinal))

 

解密String --->  new BASE64Decoder().decodeBuffer(passwordStr)

  

    public static String generatePasswordAES2(String password, String passwordKey) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128, new SecureRandom(passwordKey.getBytes("UTF-8")));
SecretKey secretKey = keyGenerator.generateKey();
byte[] encoded = secretKey.getEncoded();
SecretKey key = new SecretKeySpec(encoded, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
System.out.println("密钥的长度为:" + key.getEncoded().length);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] userPasswordBytes = password.getBytes("UTF-8");
byte[] doFinal = cipher.doFinal(userPasswordBytes);
String passwordBase64 = new String(new BASE64Encoder().encode(doFinal));
return passwordBase64;
} catch (Exception e) {
throw new BadRequestException("密码加密错误。");
}
}

  

    public static String decryptPassword(String password, String token) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128, new SecureRandom(token.getBytes("UTF-8")));
SecretKey secretKey = keyGenerator.generateKey();
byte[] encoded = secretKey.getEncoded();
SecretKey key = new SecretKeySpec(encoded, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] passwordBytes = new BASE64Decoder().decodeBuffer(password);
//解密
byte[] passwordDoFinal = cipher.doFinal(passwordBytes);
String decrypt = new String(passwordDoFinal, "UTF-8");
return decrypt;
} catch (Exception e) {
throw new BadRequestException("密码解密错误:" + e.getMessage());
}
}

  

AES-CBC-PKCS5

<script>
function getAesString(data,key,iv){//加密 var key = CryptoJS.enc.Utf8.parse(key);
//alert(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var encrypted =CryptoJS.AES.encrypt(data,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return encrypted.toString(); //返回的是base64格式的密文
}
function getDAesString(encrypted,key,iv){//解密
var key = CryptoJS.enc.Utf8.parse(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var decrypted =CryptoJS.AES.decrypt(encrypted,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
returndecrypted.toString(CryptoJS.enc.Utf8); //
}
function getAES(){ //加密
var data =document.getElementById("data-ipt").value;//明文
var key = 'abcdefgabcdefg12'; //密钥
var iv = 'abcdefgabcdefg12';
var encrypted =getAesString(data,key,iv); //密文
var encrypted1 =CryptoJS.enc.Utf8.parse(encrypted);
document.getElementById("encrypted").innerHTML = encrypted;
} function getDAes(){//解密
var encrypted =document.getElementById("encrypted").innerHTML; //密文
var key = 'abcdefgabcdefg12';
var iv = 'abcdefgabcdefg12';
var decryptedStr =getDAesString(encrypted,key,iv);
alert(decryptedStr);
document.getElementById("decrypted").innerHTML = decryptedStr;
}
</script>

  

 public static void main(String[] args)throws UnsupportedEncodingException {
Stringcontent="12345678";
Stringkey="abcdefgabcdefg12";
Stringiv="abcdefgabcdefg12";
//加密
byte[ ]encrypted=AES_CBC_Encrypt(content.getBytes(), key.getBytes(), iv.getBytes());
//解密
byte[ ]decrypted=AES_CBC_Decrypt(encrypted, key.getBytes(), iv.getBytes()); System.out.println("解密后:"+byteToHexString(decrypted));
System.out.println(byteToString(decrypted));
}
public static String byteToString(byte[ ]byte1){
returnnew String(byte1);
}
public static byte[] AES_CBC_Encrypt(byte[]content, byte[] keyBytes, byte[] iv){ try{
SecretKeySpec key = newSecretKeySpec(keyBytes, "AES");
Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE,key, new IvParameterSpec(iv));
byte[]result=cipher.doFinal(content);
return result;
}catch (Exception e) {
System.out.println("exception:"+e.toString());
}
return null;
} public static byte[] AES_CBC_Decrypt(byte[]content, byte[] keyBytes, byte[] iv){ try{
SecretKeySpec key = newSecretKeySpec(keyBytes, "AES");
Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE,key, new IvParameterSpec(iv));
byte[]result=cipher.doFinal(content);
return result;
}catch (Exception e) {
// TODO Auto-generated catchblock
System.out.println("exception:"+e.toString());
}
return null;
}
/**
* 字符串装换成base64
*
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptBASE64(Stringkey) throws Exception {
returnBase64.decodeBase64(key.getBytes());
} /**
*二进制装换成base64
*
* @param key
* @return
* @throws Exception
*/
public static String encryptBASE64(byte[]key) throws Exception {
returnnew String(Base64.encodeBase64(key));
}

  

ASE加、解密的更多相关文章

  1. ASE加解密算法详细介绍

    AEC扫盲主要增对CBC模式做详细讲解: https://blog.csdn.net/qq_28205153/article/details/55798628 AEC其他几种模式详细介绍 https: ...

  2. 学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密

      学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密 技术标签: RSA  AES  RSA AES  混合加密  整合   前言:   为了提高安全性采用了RS ...

  3. Java 加解密 AES DES TripleDes

    package xxx.common.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.crypt ...

  4. Java 加解密技术系列文章

    Java 加解密技术系列之 总结 Java 加解密技术系列之 DH Java 加解密技术系列之 RSA Java 加解密技术系列之 PBE Java 加解密技术系列之 AES Java 加解密技术系列 ...

  5. C#微信公众号开发系列教程三(消息体签名及加解密)

    http://www.cnblogs.com/zskbll/p/4139039.html C#微信公众号开发系列教程一(调试环境部署) C#微信公众号开发系列教程一(调试环境部署续:vs远程调试) C ...

  6. POCO库——Foundation组件之加解密Crypt

    加解密Crypt:内部提供多种加解密方式.信息摘要提取.随机数产生等,具体的算法内部实现不做研究学习: DigestEngine.h :DigestEngine类作为各种摘要提取的基类,提供必要的接口 ...

  7. .net core中使用openssl的公钥私钥进行加解密

    这篇博文分享的是 C#中使用OpenSSL的公钥加密/私钥解密 一文中的解决方法在 .net core 中的改进.之前的博文针对的是 .NET Framework ,加解密用的是 RSACryptoS ...

  8. rsa互通密钥对生成及互通加解密(c#,java,php)

    摘要 在数据安全上rsa起着非常大的作用,特别是数据网络通讯的安全上.当异构系统在数据网络通讯上对安全性有所要求时,rsa将作为其中的一种选择,此时rsa的互通性就显得尤为重要了. 本文参考网络资料, ...

  9. 两种JavaScript的AES加密方式(可与Java相互加解密)

    由于JavaScript属于弱类型脚本语言,因此当其与强类型的后台语言进行数据交互时会产生各种问题,特别是加解密的操作.本人由于工作中遇到用js与Java进行相互加解密的问题,在网上查了很多资料及代码 ...

  10. iOS,信息加解密

    1.AES加解密 AES加解密 // //  AESEncryptAndDecrypt.h //  NSData扩展方法,用于处理aes加解密 // //  Created by Vie on 16/ ...

随机推荐

  1. 批量删除harbor中的镜像

    一 说明 这个是我第一篇博客,所以我想放上原创的东西,尽管我一直都很担心自己写得太low,但是总要学会尝试,学会改变自己,相信自己.在写这个脚本时,由于我接触LInux不是很多,能力有限,仅仅是为了让 ...

  2. mariadb数据库的链接查询和表格设计

    链接查询 练习准备: --创建学生表 create table students ( id int unsigned not null auto_increment primary key, name ...

  3. jquery IE7 下报错:SCRIPT257: 由于出现错误 80020101 而导致此项操作无法完成

        非IE(内核)浏览器运行正常,在IE中运行异常,一般考虑为js中多了符号.     常见的有:         1.上面的html注释"<!-- -->",这种 ...

  4. 在oracle中采用connect by prior来实现递归查询

    注明:该文章为引用别人的文章,链接为:http://blog.csdn.net/apicescn/article/details/1510922 , 记录下来只是为了方便查看 原文: connect ...

  5. LeetCode——Longest Common Prefix

    Write a function to find the longest common prefix string amongst an array of strings. 写一个函数找出字符串数组中 ...

  6. [Typescript] Installing Promise Type Definitions Using the lib Built-In Types

    To fix Promise is not recolized in TypeScript, we can choose to use a lib: npm i @types/es6-promise ...

  7. [LeetCode]Median of Two Sorted Arrays 二分查找两个有序数组的第k数(中位数)

    二分.情况讨论 因为数组有序,所以能够考虑用二分.通过二分剔除掉肯定不是第k位数的区间.如果数组A和B当前处理的下标各自是mid1和mid2.则 1.假设A[mid1]<B[mid2], ①.若 ...

  8. glm编译错误问题解决 formal parameter with __declspec(align(&#39;16&#39;)) won&#39;t be aligned

    參考:http://stackoverflow.com/questions/25300116/directxxmmatrix-error-c2719-declspecalign16-wont-be-a ...

  9. Jmeter添加响应断言

    1.使用Badboy录制登录页面->import to Jmeter 2.Jmeter打开保存的文件,在登录请求下添加响应断言

  10. UE4 中的人工智能解析—ShooterGame为例

    在UE4编辑器中,打开内容浏览器,右击鼠标,创建传说中的行为树: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQTM2MzA2MjM=/font/5a6L ...