CryptoJS中AES實現前後端通用加解密技術

這篇文章主要爲大家詳細介紹了CryptoJS中AES實現前後端通用加解密技術,具有一定的參考價值,感興趣的小夥伴們可以參考一下

在項目中如果要對前後端傳輸的數據雙向加密, 比如避免使用明文傳輸用戶名,密碼等數據。 就需要對前後端數據用同種方法進行加密,方便解密。這裏介紹使用 CryptoJS 實現 AES 加解密。

首先需要下載前臺使用 CryptoJS 實現 AES 加解密的,所以要先下載組件,下載 CryptoJS-v3.1.2 版本之後,文件中包含components 和 rollups 兩個文件夾,components 文件夾下是單個組件,rollups 文件夾下是彙總,引用 rollups 下的 aes.js 文件即可。

已解決解密數據時出現的異常: exception:javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher

 這裏提供 CryptoJS-v3.1.2 的 Github鏈接

 先上後臺Java代碼: 

package com.company.pms.pmsbase.utils;
 
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
 
import org.apache.commons.codec.binary.Base64;
 
public class AesUtil {
 
 public static void main(String args[]) throws Exception {
 
  String content = "明文 123 abc";
 
  //加密
  String encrypted = encrypt(content, KEY, IV);
  //解密
  String decrypted = decrypt(encrypted, KEY, IV);
 
  System.out.println("加密前:" + content);
 
  System.out.println("加密後:" + encrypted);
 
  System.out.println("解密後:" + decrypted);
 }
 
 private static String KEY = "abcdef0123456789"; // 長度必須是 16
 
 private static String IV = "abcdef0123456789"; // 長度必須是 16
 
 /**
  * 加密返回的數據轉換成 String 類型
  * @param content 明文
  * @param key 祕鑰
  * @param iv 初始化向量是16位長度的字符串
  * @return
  * @throws Exception
  */
 public static String encrypt(String content, String key, String iv) throws Exception {
  // 將返回的加密過的 byte[] 轉換成Base64編碼字符串 !!!!很關鍵
  return base64ToString(AES_CBC_Encrypt(content.getBytes(), key.getBytes(), iv.getBytes()));
 }
 
 /**
  * 將解密返回的數據轉換成 String 類型
  * @param content Base64編碼的密文
  * @param key 祕鑰
  * @param iv 初始化向量是16位長度的字符串
  * @return
  * @throws Exception
  */
 public static String decrypt(String content, String key, String iv) throws Exception {
  // stringToBase64() 將 Base64編碼的字符串轉換成 byte[] !!!與base64ToString()配套使用
  return new String(AES_CBC_Decrypt(stringToBase64(content), key.getBytes(), iv.getBytes()));
 }
 
 private static byte[] AES_CBC_Encrypt(byte[] content, byte[] keyBytes, byte[] iv){
  try {
   SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
   Cipher cipher = 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;
 }
 
 private static byte[] AES_CBC_Decrypt(byte[] content, byte[] keyBytes, byte[] iv){
  try {
   SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
   Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
   cipher.init(Cipher.DECRYPT_MODE,key, new IvParameterSpec(iv));
   byte[] result = cipher.doFinal(content);
   return result;
  } catch (Exception e) {
   System.out.println("exception:"+e.toString());
  }
  return null;
 }
 
 /**
  * 字符串裝換成 Base64
  */
 
 public static byte[] stringToBase64(String key) throws Exception {
  return Base64.decodeBase64(key.getBytes());
 }
 
 /**
  * Base64裝換成字符串
  */
 public static String base64ToString(byte[] key) throws Exception {
  return new Base64().encodeToString(key);
 }
 
}

再上前端代碼(需引用 rollups 目錄下的 aes.js ):

function encodeAesString(data,key,iv){
 var key = CryptoJS.enc.Utf8.parse(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 
 });
 //返回的是base64格式的密文 
 return encrypted;
}
 
// encrypted 爲是base64格式的密文
function decodeAesString(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
 });
 return decrypted.toString(CryptoJS.enc.Utf8);
}
 
// 測試加、解密
function testAES(){
 var data = "明文 123 abc"; // 明文 
 var key = 'abcdef0123456789'; // 密鑰 長度16
 var iv = 'abcdef0123456789'; // 密鑰 長度16
 
 console.log("加密前:" + data);
 
 // 測試加密
 var encrypted = encodeAesString(data,key,iv); // 密文
 console.log("加密後: " + encrypted);
 
 var decryptedStr = decodeAesString(encrypted,key,iv);
 console.log("解密後: " + decryptedStr);
}

貼上效果圖:

中間遇到的問題: 

    1.  祕鑰問題, 祕鑰的長度必須爲16位, 否則會報錯

    2. 加密得到的 byte[] 需用使用Base64轉換成字符串, 不能直接轉成字符串,因爲加密所採用的AES, MD5, SHA-256, SHA-512 等等算法,它們是通過對byte[] 進行各種變換和運算,得到加密之後的byte[],那麼這個加密之後的 byte[] 結果顯然 就不會符合任何一種的編碼方案,比如 UTF-8, GBK等,因爲加密的過程是任意對byte[]進行運算的。所以你用任何一種編碼方案來解碼 加密之後的 byte[] 結果,得到的都會是亂碼。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持神馬文庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章