前端CryptoJS加密、后端JAVA解密代碼實(shí)現(xiàn)參考
前端的朋友可能會(huì)關(guān)注前端js加密,我們?cè)谧?WEB 的登錄功能時(shí)一般是通過 Form 提交或 Ajax 方式提交到服務(wù)器進(jìn)行驗(yàn)證的。為了防止抓包,登錄密碼肯定要先進(jìn)行一次加密(RSA),再提交到服務(wù)器進(jìn)行驗(yàn)證。
1、使用AES算法的CBC模式加密
1.1、前端加密代碼實(shí)現(xiàn)參考
vue項(xiàng)目需要安裝CryptoJS安裝包,安裝命令如下:
npm install crypto-js
在項(xiàng)目中引入CryptoJS
import CryptoJS from 'crypto-js'
參考代碼如下:
<script> // 此處key為16進(jìn)制 let key = '385f33cb91484b04a177828829081ab7'; console.log('密鑰:', key); // key格式化處理 key = CryptoJS.enc.Utf8.parse(key) // 偏移量長度為16位, 注:偏移量需要與后端定義好,保證一致 let iv = "37fa77f6a3b0462d"; iv = CryptoJS.enc.Utf8.parse("37fa77f6a3b0462d"); // 加密內(nèi)容 const source = { "username": "用戶名", "password": "密碼", "timestamp": new Date().getTime() } const content = JSON.stringify(source); console.log('加密前:', source); // 加密方法 const encryptedContent = CryptoJS.AES.encrypt(content, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }) const encStr = encryptedContent.ciphertext.toString() console.log("加密后:", encStr); // 解密方法 const decryptedContent = CryptoJS.AES.decrypt(CryptoJS.format.Hex.parse(encStr), key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }) console.log('解密:',CryptoJS.enc.Utf8.stringify(decryptedContent)); </script>
前端打印結(jié)果
說明:
1> CBC模式前、后端需要確定偏移量的值,并且保持一致,這樣才能確保后端解密成功。
2> 前端CBC模式或者ECB模式下的填充方式 Pkcs7,對(duì)應(yīng)后端AES算法模式中的 PKCS5Padding 填充方式
3> CryptoJS對(duì)應(yīng)的API文檔地址:https://cryptojs.gitbook.io/docs/#encoders
1.2、后端解密代碼實(shí)現(xiàn)參考
后端代碼實(shí)現(xiàn)需要引入的maven依賴如下:
<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.15</version> </dependency>
參考代碼實(shí)現(xiàn)如下:
import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; /** * AES對(duì)稱加密工具類 * * @author 星空流年 */ public class AesUtil { /** * 偏移量 * * 說明:偏移量字符串必須是16位 當(dāng)模式是CBC的時(shí)候必須設(shè)置偏移量 * 此處值與前端偏移量值保持一致 */ private static String iv = "37fa77f6a3b0462d"; /** * 加密算法 */ private static String Algorithm = "AES"; /** * 算法/模式/補(bǔ)碼方式 */ private static String AlgorithmProvider = "AES/CBC/PKCS5Padding"; /** * 加密 * * @param src 加密內(nèi)容 * @param uniqueKey 加密key * @return * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidAlgorithmParameterException * @throws UnsupportedEncodingException */ public static String encrypt(String src, String uniqueKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, UnsupportedEncodingException { byte[] key = uniqueKey.getBytes(); SecretKey secretKey = new SecretKeySpec(key, Algorithm); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8")); Cipher cipher = Cipher.getInstance(AlgorithmProvider); cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); byte[] cipherBytes = cipher.doFinal(src.getBytes("UTF-8")); return byteToHexString(cipherBytes); } /** * 解密 * * @param enc 加密內(nèi)容 * @param uniqueKey 唯一key * @return * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException * @throws InvalidAlgorithmParameterException * @throws InvalidKeyException * @throws DecoderException * @throws BadPaddingException * @throws IllegalBlockSizeException */ public static String decrypt(String enc, String uniqueKey) throws NoSuchPaddingException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidAlgorithmParameterException, InvalidKeyException, DecoderException, BadPaddingException, IllegalBlockSizeException { byte[] key = uniqueKey.getBytes(); SecretKey secretKey = new SecretKeySpec(key, Algorithm); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8")); Cipher cipher = Cipher.getInstance(AlgorithmProvider); cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec); byte[] hexBytes = hexStringToBytes(enc); byte[] plainBytes = cipher.doFinal(hexBytes); return new String(plainBytes, "UTF-8"); } /** * 將byte數(shù)組轉(zhuǎn)換為16進(jìn)制字符串 * * @param src * @return */ private static String byteToHexString(byte[] src) { return Hex.encodeHexString(src); } /** * 將16進(jìn)制字符串轉(zhuǎn)換為byte數(shù)組 * * @param hexString * @return */ private static byte[] hexStringToBytes(String hexString) throws DecoderException { return Hex.decodeHex(hexString); } /** * AES加密、解密測(cè)試方法 * * @param args */ public static void main(String[] args) { try { // 唯一key作為密鑰 String uniqueKey = "385f33cb91484b04a177828829081ab7"; // 加密前數(shù)據(jù),此處數(shù)據(jù)與前端數(shù)據(jù)一致(加密內(nèi)容包含有時(shí)間戳),請(qǐng)注意查看前端加密前數(shù)據(jù) String src = "{\"username\":\"用戶名\",\"password\":\"密碼\",\"timestamp\":1628218094188}"; System.out.println("密鑰:" + uniqueKey); System.out.println("原字符串:" + src); // 加密 String encrypt = encrypt(src, uniqueKey); System.out.println("加密:" + encrypt); // 解密 String decrypt = decrypt(encrypt, uniqueKey); System.out.println("解密:" + decrypt); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
測(cè)試結(jié)果
2、使用AES算法的ECB模式加密
前面也說到,AES的ECB和CBC模式下的填充方式 Pkcs7,對(duì)應(yīng)后端AES算法模式中的 PKCS5Padding 填充方式,只不過CBC模式需要添加偏移量,而ECB模式則不需要,大體實(shí)現(xiàn)方式本質(zhì)上沒有太大差別。
2.1、前端加密代碼實(shí)現(xiàn)參考
vue項(xiàng)目需要安裝CryptoJS安裝包,安裝命令如下:
npm install crypto-js
在項(xiàng)目中引入CryptoJS
import CryptoJS from 'crypto-js'
參考代碼如下:
<script> // 此處key為16進(jìn)制 let key = '385f33cb91484b04a177828829081ab7'; console.log('密鑰:', key); // key格式化處理 key = CryptoJS.enc.Utf8.parse(key) // 加密內(nèi)容 const source = { "username": "用戶名", "password": "密碼", "timestamp": new Date().getTime() } const content = JSON.stringify(source); console.log('加密前:', source); // 加密方法 const encryptedContent = CryptoJS.AES.encrypt(content, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }) const encStr = encryptedContent.ciphertext.toString() console.log('加密后:', encStr); // 解密方法 const decryptedContent = CryptoJS.AES.decrypt(CryptoJS.format.Hex.parse(encStr), key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }) console.log('解密:',CryptoJS.enc.Utf8.stringify(decryptedContent)); </script>
前端打印結(jié)果
2.2、后端加密代碼實(shí)現(xiàn)參考
import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; /** * AES對(duì)稱加密工具類 * * @author 星空流年 */ public class AesUtil { /** * 加密算法 */ private static String Algorithm = "AES"; /** * 算法/模式/補(bǔ)碼方式 */ private static String AlgorithmProvider = "AES/ECB/PKCS5Padding"; /** * 加密 * * @param src 原內(nèi)容 * @param uniqueKey 唯一key * @return * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws DecoderException */ public static String encrypt(String src, String uniqueKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, DecoderException { byte[] key = uniqueKey.getBytes(); SecretKey secretKey = new SecretKeySpec(key, Algorithm); Cipher cipher = Cipher.getInstance(AlgorithmProvider); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] cipherBytes = cipher.doFinal(src.getBytes(StandardCharsets.UTF_8)); return byteToHexString(cipherBytes); } /** * 解密 * * @param enc 加密內(nèi)容 * @param uniqueKey 唯一key * @return * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException * @throws InvalidAlgorithmParameterException * @throws InvalidKeyException * @throws DecoderException * @throws BadPaddingException * @throws IllegalBlockSizeException */ public static String decrypt(String enc, String uniqueKey) throws NoSuchPaddingException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidAlgorithmParameterException, InvalidKeyException, DecoderException, BadPaddingException, IllegalBlockSizeException { byte[] key = uniqueKey.getBytes(); SecretKey secretKey = new SecretKeySpec(key, Algorithm); Cipher cipher = Cipher.getInstance(AlgorithmProvider); cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] hexBytes = hexStringToBytes(enc); byte[] plainBytes = cipher.doFinal(hexBytes); return new String(plainBytes, SystemConstants.UTF_8); } /** * 將byte數(shù)組轉(zhuǎn)換為16進(jìn)制字符串 * * @param src * @return */ private static String byteToHexString(byte[] src) { return Hex.encodeHexString(src); } /** * 將16進(jìn)制字符串轉(zhuǎn)換為byte數(shù)組 * * @param hexString * @return */ private static byte[] hexStringToBytes(String hexString) throws DecoderException { return Hex.decodeHex(hexString); } /** * AES加密、解密測(cè)試方法 * * @param args */ public static void main(String[] args) { try { // 唯一key作為密鑰 String uniqueKey = "385f33cb91484b04a177828829081ab7"; // 加密前數(shù)據(jù),此處數(shù)據(jù)與前端數(shù)據(jù)一致(加密內(nèi)容包含有時(shí)間戳),請(qǐng)注意查看前端加密前數(shù)據(jù) String src = "{\"username\":\"用戶名\",\"password\":\"密碼\",\"timestamp\":1628220492939}"; System.out.println("密鑰:" + uniqueKey); System.out.println("原字符串:" + src); // 加密 String encrypt = encrypt(src, uniqueKey); System.out.println("加密:" + encrypt); // 解密 String decrypt = decrypt(encrypt, uniqueKey); System.out.println("解密:" + decrypt); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
測(cè)試結(jié)果
到此這篇關(guān)于前端CryptoJS加密、后端解密代碼實(shí)現(xiàn)參考的文章就介紹到這了,更多相關(guān)前端CryptoJS加密、后端解密代碼實(shí)現(xiàn)參考內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- js前端加密庫Crypto-js進(jìn)行MD5/SHA256/BASE64/AES加解密的方法與示例
- JavaScript實(shí)現(xiàn)的前端AES加密解密功能【基于CryptoJS】
- JS使用插件cryptojs進(jìn)行加密解密數(shù)據(jù)實(shí)例
- VueJs里利用CryptoJs實(shí)現(xiàn)加密及解密的方法示例
- 使用JS前端加密庫sm-crypto實(shí)現(xiàn)國密sm2、sm3和sm4加密與解密
- vue項(xiàng)目中使用crypto-js實(shí)現(xiàn)加密解密方式
- JS使用 cryptojs加密解密(對(duì)稱加密庫)的問題
- vue項(xiàng)目之前端CryptoJS加密、解密代碼示例
- vue用CryptoJS加密,java用CryptoUtil解密
- crypto-js對(duì)稱加密解密的使用方式詳解(vue與java端)
相關(guān)文章
Bootstrap中文本框的寬度變窄并且加入一副驗(yàn)證碼圖片的實(shí)現(xiàn)方法
這篇文章主要介紹了Bootstrap中文本框的寬度變窄并且加入一副驗(yàn)證碼圖片的實(shí)現(xiàn)方法的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06淺談webpack 構(gòu)建性能優(yōu)化策略小結(jié)
webpack以其豐富的功能和靈活的配置而深受業(yè)內(nèi)吹捧,逐步取代了grunt和gulp成為大多數(shù)前端工程實(shí)踐中的首選,這篇文章主要介紹了淺談webpack 構(gòu)建性能優(yōu)化策略小結(jié),感興趣的小伙伴們可以參考一下2018-06-06js遍歷獲取表格內(nèi)數(shù)據(jù)的方法(必看)
下面小編就為大家?guī)硪黄猨s遍歷獲取表格內(nèi)數(shù)據(jù)的方法(必看)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04詳解如何在 JavaScript 中使用三元運(yùn)算符
這篇文章主要為大家介紹了詳解如何在 JavaScript 中使用三元運(yùn)算符示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10mpvue微信小程序多列選擇器用法之省份城市選擇的實(shí)現(xiàn)
這篇文章主要給大家介紹了關(guān)于mpvue微信小程序多列選擇器用法之省份城市選擇實(shí)現(xiàn)的相關(guān)資料,文中通過示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03