您的位置:首页 > Web前端

服务端AES加密解密,前端crypto-js加密解密

2017-02-09 00:00 671 查看
摘要: 加密方式:AES/CBC/PKCS5Padding+BASE64
前端:crypto-js解密

###服务端
      服务端采用AES对称加密算法。

     
AES是基于数据块的加密方式,每次处理的数据是一块(16字节),当数据不是16字节的倍数时自动填充OR手动填充(填充方式取决于使用哪种填充方式)。

     
支持的模式包括:

ECB:是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。

CBC:是一种循环模式,前一个分组的密文和当前分组的明文异或操作后再加密,这样做的目的是增强破解难度。

CFB/OFB实际上是一种反馈模式,目的也是增强破解的难度。

ECB和CBC的加密结果是不一样的,两者的模式不同,而且CBC会在第一个密码块运算时加入一个初始化向量。

     
补码方式包括:NoPadding,PKCS5Padding,ISO10126Padding;

个人观点:补码方式的选择依据解码端,例如OC解码需要使用noPadding,crypto-js解码需要使用PKCS5Padding

加密代码:

/**
*  encryptToAESPKCS5:加密AES
*
* @param content : 加密内容
* @param password : 加密密钥
* @return
*/
public static String encryptToAESPKCS5(String content, String password) {
byte[] encryptResult = null;
try {
// 密钥
SecretKeySpec secretKey = new SecretKeySpec(password.getBytes(), "AES");
// 算法/模式/填充
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] byteContent = content.getBytes("utf-8");
// 初始化向量,在密钥相同的前提下,加上初始化向量,相同内容加密后相同
IvParameterSpec zeroIv = new IvParameterSpec(password.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, secretKey, zeroIv);
encryptResult = cipher.doFinal(byteContent);

}
catch(Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return Base64.getEncoder().encodeToString(encryptResult);
}

解密代码:

/**
* decryptToAESPKCS5:解密AES
*
* @param content : 解密内容
* @param password : 解密密钥
* @return
*/
public static String decryptToAESPKCS5(String content, String password) {
byte[] decryptResult = null;
try {
// 密钥
SecretKeySpec secretKey = new SecretKeySpec(password.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// base64转换
byte[] byteContent = Base64.getDecoder().decode(content);
IvParameterSpec zeroIv = new IvParameterSpec(password.getBytes());
cipher.init(Cipher.DECRYPT_MODE, secretKey, zeroIv);
decryptResult = cipher.doFinal(byteContent);

String originalString = new String(decryptResult, "utf-8");
return originalString;
}
catch(Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}

注意:
1.密钥(代码中的password)必须是16位;

2.加密内容必须为16的倍数,在PKCS5Padding、ISO10126Padding填充模式下会自动补位,在noPadding填充模式下需要自己进行补位;

###前端
      前端采用开源crypto-js工具。https://www.npmjs.com/package/crypto-js

/**
* [encrypt 加密]
* @return {[type]} [description]
*/
function encrypt() {
var content = $("#encryptContent").val();
var encryptResult = CryptoJS.AES.encrypt(content, key, {
iv: key,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
$("#encryptResult").val(encryptResult);
}

/**
* [decrypt 解密]
* @return {[type]} [description]
*/
function decrypt() {
var content = $("#decryptContent").val();
var bytes = CryptoJS.AES.decrypt(content.toString(), key, {
iv: key,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
var decryptResult = bytes.toString(CryptoJS.enc.Utf8);
$("#decryptResult").val(decryptResult);
}

注意:如果结合服务端加密内容使用crypto-js进行解密,无需进行BASE64解码

服务端源码github:https://github.com/kris-J/java-aes-encrypt

前端源码github:https://github.com/kris-J/aesEncrypt-use-Crypto-js
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java AESCrypt Crypto-JS