最近在項目中遇到aes加解密128位ecb模式(在內容和key確定的情況下加密出來的內容是固定不變的),開始java後端的aes加解密是把內容加密後的字節數組encode_content直接發送給Java後端,這樣導致前端vue中的aes加解密不能和Java後臺互通,原因是前端vue加解密傳輸的內容是字符串,不能直接傳輸byte數組,所以無法互通。如果要實現跨平臺通用最好不要直接傳輸字節數組。
aes加密後的內容輸出格式可以是十六進制的字符串也可以是base64加密的字符串。
通用的後端算法如下,
public static String enCode(String content, String key) {
if (key == null || "".equals(key)) {
logger.info("key爲空!");
return null;
}
if (key.length() != 16) {
logger.info("key長度不是16位!");
return null;
}
try {
byte[] raw = key.getBytes(); //獲得密碼的字節數組
SecretKeySpec skey = new SecretKeySpec(raw, "AES"); //根據密碼生成AES密鑰
Cipher cipher = Cipher.getInstance(ALGORITHM); //根據指定算法ALGORITHM自成密碼器
cipher.init(Cipher.ENCRYPT_MODE, skey); //初始化密碼器,第一個參數爲加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二個參數爲生成的AES密鑰
byte [] byte_content = content.getBytes("utf-8"); //獲取加密內容的字節數組(設置爲utf-8)不然內容中如果有中文和英文混合中文就會解密爲亂碼
byte [] encode_content = cipher.doFinal(byte_content); //密碼器加密數據
return Base64.encodeBase64String(encode_content); //將加密後的數據轉換爲字符串返回
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
後端的解密方法:
public static String deCode(String content, String key) {
if (key == null || "".equals(key)) {
logger.info("key爲空!");
return null;
}
if (key.length() != 16) {
logger.info("key長度不是16位!");
return null;
}
try {
byte[] raw = key.getBytes(); //獲得密碼的字節數組
SecretKeySpec skey = new SecretKeySpec(raw, "AES"); //根據密碼生成AES密鑰
Cipher cipher = Cipher.getInstance(ALGORITHM); //根據指定算法ALGORITHM自成密碼器
cipher.init(Cipher.DECRYPT_MODE, skey); //初始化密碼器,第一個參數爲加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二個參數爲生成的AES密鑰
byte [] encode_content = Base64.decodeBase64(content); //把密文字符串轉回密文字節數組
byte [] byte_content = cipher.doFinal(encode_content); //密碼器解密數據
return new String(byte_content,"utf-8"); //將解密後的數據轉換爲字符串返回
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
這樣的話在vue等js前端也可以和java平臺的aes加解密互通;
前端加密解密實現:引入crypto.js
/*****************************************************
* AES加密
* @param content 加密內容
* @param key 加密密碼,由字母或數字組成
此方法使用AES-128-ECB加密模式,key需要爲16位
加密解密key必須相同,如:abcd1234abcd1234
* @return 加密密文
****************************************************/
function encrypt(content, key){
var sKey = CryptoJS.enc.Utf8.parse(key);
var sContent = CryptoJS.enc.Utf8.parse(content);
var encrypted = CryptoJS.AES.encrypt(sContent, sKey, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
return encrypted.toString();
}
/*****************************************************
* AES解密
* @param content 加密密文
* @param key 加密密碼,由字母或數字組成
此方法使用AES-128-ECB加密模式,key需要爲16位
加密解密key必須相同,如:abcd1234abcd1234
* @return 解密明文
****************************************************/
function decrypt(content, key){
var sKey = CryptoJS.enc.Utf8.parse(key);
var decrypt = CryptoJS.AES.decrypt(content, sKey, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
return CryptoJS.enc.Utf8.stringify(decrypt).toString();
}
注:此方法爲AES,128位,ECB模式加密解密。
前後端只要保持key相同,可以相互加密解密。