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. POJ 2311 Cutting Game(SG函数)

    题目描述 意思就是说两个人轮流剪纸片,直到有一个人剪出1*1的方格就算这个人赢了.然后给出纸片的长和宽,求先手会赢还是会输 (1<=n,m<=200) 题解 看了一眼,这不是裸的SG吗 啪 ...

  2. java+jsp+sqlserver实现简单的增删改查操作 连接数据库代码

    1,网站系统开发需要掌握的技术 (1)网页设计语言,html语言css语言等 (2)Java语言 (3)数据库 (4)等 2,源程序代码 (1) 连接数据库代码 package com.jaovo.m ...

  3. 二维码框架ZBarSDK的使用和自己定义二维码扫描界面方法

    假设你不知道ZBarSDK怎么用,请下载demo http://download.csdn.net/detail/u013686641/7858917 假设你已经配置好ZBarSDK .那么以下这个类 ...

  4. SQLSever: 怎样在select中的每一行产生不同的随机数?

    select 的随机函数有点假, 或许是由于它是基于时间来的吧, 同一select中由于时间无法错开导致产生的随机数都是一样的. 怎样做到让不同的行拥有不同的随机数呢? 以下以产生某个月的随机日期来演 ...

  5. 拥抱PBO(基于项目的组织)聚焦核心价值创造

    近年来.PBO(Project-Based Organizations)作为一种新兴的整合各类专业智力资源和专业知识的组织结构,受到越来越多的关注,第五版PMBOK出现的新词汇.三种组织(职能型.矩阵 ...

  6. Linux 经常使用快捷键

    桌面下: Alt+F5   取消最大化窗体 Alt+F9   最小化窗体  Alt+F10  最大化窗体  Alt+空格 打开窗体的控制菜单 (点击窗体左上角图标出现的菜单)     ctl+r   ...

  7. 8.ES6测试

    转自:http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html 如果测试脚本是用ES6写的,那么运行测试之前,需 ...

  8. hive查询不加分区的一个异常

    今天下午有同事反馈她提交了了一个SQL后,hive 查询就停止响应了. 我看了下,发现hiveserver确实hug住了.听过查看日志,发现了一个牛逼的SQL, 这个SQL很简单: select a. ...

  9. Spring MVC登录注册以及转换json数据

    项目结构; 代码如下: BookController package com.mstf.controller; import javax.servlet.http.HttpServletRespons ...

  10. nginx的Rewrite重写

        location /{                if ($remote_addr=192.168.1.100){                          //禁止此 ip 访问 ...