最近安全要求登錄必須密文傳參,於是決定找個前端插件來加密,就簡單的用AES吧,雖說密碼推薦的是非對稱加密,但這只是個簡單的內部小系統,安全也沒要求那么嚴格。
發現 cryptojs 使用比較方便,git地址:https://github.com/brix/crypto-js/tree/master,需要源碼的的可以切換到 develop 版本下載。
寫本文時版本為:4.0.0
話不多說,直接上代碼了。
前端加密:
// 前端加密。 import { AES, mode, pad, enc } from 'crypto-js'; let Key = enc.Utf8.parse("MpWsyseHtJywNON8");// 秘鑰長度需要是16的倍數,且需要進行Utf8轉義。 let aesUid: any = AES.encrypt("賬號", Key, { mode: mode.ECB, padding: pad.Pkcs7 }).ciphertext.toString(); // 注意此處 ciphertext 表示16進制 let aesPwd: any = AES.encrypt("密碼", Key, { mode: mode.ECB, padding: pad.Pkcs7 }).ciphertext.toString();
網上許多資料,包括官方git都沒有說要 .ciphertext.toString(),導致開發中后端java始終無法正常解密,可能是新版本的緣故,個人實踐發現需要用 .ciphertext.toString() 轉換為16進制,后端才好解密。
后端java解密:
private static String html_aesKey = "MpWsyseHtJywNON8"; /** * PKCS5Padding -- Pkcs7 兩種padding方法都可以 * @param content 3c2b1416d82883dfeaa6a9aa5ecb8245 16進制 * @param key * @return */ public static String decryptAES2(String content) { try { SecretKeySpec skeySpec = new SecretKeySpec(html_aesKey.getBytes("UTF-8"), "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // "算法/模式/補碼方式" cipher.init(Cipher.DECRYPT_MODE, skeySpec); return new String(cipher.doFinal(parseHexStr2Byte(content))); } catch (Exception e) { e.printStackTrace(); } return null; } /**將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; }