在项目中如果要对前后端传输的数据双向加密, 比如避免使用明文传输用户名,密码等数据。 就需要对前后端数据用同种方法进行加密,方便解密。这里介绍使用 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[] 结果,得到的都会是乱码。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 第五街的士高《印度激情版》3CD [WAV+CUE][2.4G]
- 三国志8重制版哪个武将智力高 三国志8重制版智力武将排行一览
- 三国志8重制版哪个武将好 三国志8重制版武将排行一览
- 三国志8重制版武将图像怎么保存 三国志8重制版武将图像设置方法
- 何方.1990-我不是那种人【林杰唱片】【WAV+CUE】
- 张惠妹.1999-妹力新世纪2CD【丰华】【WAV+CUE】
- 邓丽欣.2006-FANTASY【金牌大风】【WAV+CUE】
- 饭制《黑神话》蜘蛛四妹手办
- 《燕云十六声》回应跑路:年内公测版本完成95%
- 网友发现国内版《双城之战》第二季有删减:亲亲环节没了!
- 邓丽君2024-《漫步人生路》头版限量编号MQA-UHQCD[WAV+CUE]
- SergeProkofievplaysProkofiev[Dutton][FLAC+CUE]
- 永恒英文金曲精选4《TheBestOfEverlastingFavouritesVol.4》[WAV+CUE]
- 群星《国风超有戏 第9期》[320K/MP3][13.63MB]
- 群星《国风超有戏 第9期》[FLAC/分轨][72.56MB]