//AES加密
function encrypt(context) {
var encrypted = '';
if (typeof(context) == 'object') {
context = JSON.stringify(context);
}
var srcs = CryptoJS.enc.Utf8.parse(context);
encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString()
}
// AES解密
function decrypt(context) {
var decrypt = CryptoJS.AES.decrypt(context, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;
/**
* 对称加密解密AES算法
*
* @author JustryDeng
* @date 2018年7月20日 下午6:12:35
*/
public class AESEncryptAndDecryptUtil {
/** 对应:算法/模式/补码方式 */
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
/** 高级加密标准算法 */
private static final String ALGORITHM = "AES";
/** 字符编码 */
private static final String CHARSET = "utf-8";
/** 必须16位 must be 16 bytes long */
private static final String IV = "A-16-Byte-String";
/**
* key为 [16位字节长度 或 24位字节长度 或者 32位字节长度]的字符串 注: key不要是中文
* 注:我们可以定死key,也可以通过传参来获取传过来的key(本人采用传参的方式,所以这个属性注释掉了)
*/
// private static final String KEY = "A-16-Byte-keyVal";
/**
* 加密
*
* @param context
* 要加密的字符串数据
* @param key
* 秘钥
* @return 加密后的数据字符串
* @date 2018年7月20日 下午6:17:44
*/
public static String encrypt(String context, String key) {
try {
byte[] decode = context.getBytes(CHARSET);
byte[] bytes = createKeyAndIv(decode, Cipher.ENCRYPT_MODE, key);
return Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
*
* @param context
* 要解密的字符串数据
* @param key
* 对应的秘钥(不论是前端还是后端加的密,key都要和加密时的一样)
* @return 解密后的数据字符串
* @date 2018年7月20日 下午6:18:35
*/
public static String decrypt(String context, String key) {
try {
Base64.Decoder decoder = Base64.getDecoder();
byte[] decode = decoder.decode(context);
byte[] bytes = createKeyAndIv(decode, Cipher.DECRYPT_MODE, key);
return new String(bytes, CHARSET);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 与cipherFilter方法配合,获取加密/解密后的字节数组
*
* @date 2018年7月20日 下午6:21:34
*/
public static byte[] createKeyAndIv(byte[] context, int opmode, final String key) throws Exception {
byte[] keyArray = key.getBytes(CHARSET);
byte[] iv = IV.getBytes(CHARSET);
return cipherFilter(context, opmode, keyArray, iv);
}
public static byte[] cipherFilter(byte[] context, int opmode, byte[] key, byte[] iv) throws Exception {
Key secretKeySpec = new SecretKeySpec(key, ALGORITHM);
AlgorithmParameterSpec ivParameterSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(opmode, secretKeySpec, ivParameterSpec);
return cipher.doFinal(context);
}
}
import com.aspire.util.AESEncryptAndDecryptUtil;
/**
* 以主函数进行测试
*
* @author JustryDeng
* @date 2018年7月20日 下午6:40:05
*/
public class Test {
public static void main(String[] args) {
// 16个 或 24个 或 32个 字节长度 即可(注:不要是中文)
String key = "key0123456789key";
String context = "JustryDeng";
System.out.println("原数据:" + context);
// 加密
String encrypt = AESEncryptAndDecryptUtil.encrypt(context, key);
System.out.println("加密后:" + encrypt);
// 解密
String decrypt = AESEncryptAndDecryptUtil.decrypt(encrypt, key);
System.out.println("解密后:" + decrypt);
}
}
package com.aspire.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.aspire.util.AESEncryptAndDecryptUtil;
/**
* 前端对称加密 给 后端加密
*
* @author JustryDeng
* @date 2018年7月20日 下午3:19:44
*/
@RestController
public class EncryptAndDecryptController {
// KEY要与前端加密时保持一致(且:应为:16或24或32字节长度)
private static final String KEY = "A-16-Byte-keyVal";
/**
*
*
* @param encryptedTarget
* 加密后的数据字符串
* @return
* @date 2018年7月20日 下午6:47:28
*/
@RequestMapping("/EncryptAndDecryptTest")
public String test(@RequestParam("encryptedTarget") String encryptedTarget) {
StringBuffer sb = new StringBuffer();
try {
// 调用后端AES加密解密工具类(在上面的示例中以给出)
String decryptTarget = AESEncryptAndDecryptUtil.decrypt(encryptedTarget,KEY);
sb.append(">>>解密前:" + encryptedTarget);
sb.append(">>>解密前的内容长度:" + encryptedTarget.length());
sb.append(">>>加密密钥和解密密钥:" + KEY);
sb.append(">>>解密后:" + decryptTarget);
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
}
加密demo
由此可见:前端加密,后端解密,成功!