1. 程式人生 > 其它 >vue前後端rsa+aes混合加密_AES前後端對稱加密

vue前後端rsa+aes混合加密_AES前後端對稱加密

技術標籤:vue前後端rsa+aes混合加密

概述

高階加密標準(AES,Advanced Encryption Standard)為最常見的對稱加密演算法,對稱加密演算法即加密和解密的過程使用同一個祕鑰進行加密。本文從實用的角度去描述前後端使用AES對稱加密。

需求分析

前端請求資料傳遞引數時,需要對其進行加密,而不是使用明文進行傳輸,防止http請求被人截獲而獲取到資訊,AES對稱加密就是一種方式,前端對密碼進行加密,傳輸給後端,後端獲取之後使用和前端約定好的祕鑰進行解密。

前端AES加解密

前端加密需要引入crypto-js的js檔案,crypto-js是加密標準的JavaScript庫,實現了各種加密演算法,下載地址:https://www.yuque.com/docs/share/a764ecd9-3f47-4d40-8ec6-b80aca710d38?# 《前後端加密crypto-js.js檔案》

實操,demo如下

前端AES加解密程式碼:

// 金鑰var key = '38373134313330303030333134313738'; key = CryptoJS.enc.Hex.parse(key) var iv = CryptoJS.enc.Hex.parse("303132333435233454243444546")  var src = mobile_phone; console.log('原字串:', src);                    var enc = CryptoJS.AES.encrypt(src ,key,{                        iv:iv,                        mode: CryptoJS.mode.CBC,                        padding: CryptoJS.pad.Pkcs7                    })                    console.log('加密:',enc.toString());                    var enced = enc.ciphertext.toString()                     console.log("加密:", enced);                    var dec = CryptoJS.AES.decrypt(CryptoJS.format.Hex.parse(enced), key,{                        iv:iv,                        mode: CryptoJS.mode.CBC,                        padding: CryptoJS.pad.Pkcs7                    })                    console.log('解密:',CryptoJS.enc.Utf8.stringify(dec));                    

其中key和iv的值並不是隨意填寫的,這個是需要後端加解密生成後給到前端使用

後端AES加解密:

package unis.cloud.data.tool;import java.io.UnsupportedEncodingException;import java.nio.charset.Charset;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;public class AesTool { private static String iv = "0123456789ABCDEF";//偏移量字串必須是16位 當模式是CBC的時候必須設定偏移量    private static String Algorithm = "AES";    private static String AlgorithmProvider = "AES/CBC/PKCS5Padding"; //演算法/模式/補碼方式    public static byte[] generatorKey() throws NoSuchAlgorithmException {        KeyGenerator keyGenerator = KeyGenerator.getInstance(Algorithm);        keyGenerator.init(256);//預設128,獲得無政策許可權後可為192或256        SecretKey secretKey = keyGenerator.generateKey();        return secretKey.getEncoded();    }    public static IvParameterSpec getIv() throws UnsupportedEncodingException {        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));        System.out.println("偏移量:"+byteToHexString(ivParameterSpec.getIV()));        return ivParameterSpec;    }    public static byte[] encrypt(String src) throws NoSuchAlgorithmException, NoSuchPaddingException,            InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {    byte key[] = "87000078".getBytes("utf-8");    SecretKey secretKey = new SecretKeySpec(key, Algorithm);        IvParameterSpec ivParameterSpec = getIv();        Cipher cipher = Cipher.getInstance(AlgorithmProvider);        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);        byte[] cipherBytes = cipher.doFinal(src.getBytes(Charset.forName("utf-8")));        return cipherBytes;    }    public static byte[] decrypt(String src) throws Exception {    byte key[] = "87000078".getBytes("utf-8");    SecretKey secretKey = new SecretKeySpec(key, Algorithm);        IvParameterSpec ivParameterSpec = getIv();        Cipher cipher = Cipher.getInstance(AlgorithmProvider);        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);        byte[] hexBytes = hexStringToBytes(src);        byte[] plainBytes = cipher.doFinal(hexBytes);        return plainBytes;    }    /**     * 將byte轉換為16進位制字串     * @param src     * @return     */    public static String byteToHexString(byte[] src) {        StringBuilder sb = new StringBuilder();        for (int i = 0; i < src.length; i++) {            int v = src[i] & 0xff;            String hv = Integer.toHexString(v);            if (hv.length() < 2) {                sb.append("0");            }            sb.append(hv);        }        return sb.toString();    }    /**     * 將16進位制字串裝換為byte陣列     * @param hexString     * @return     */    public static byte[] hexStringToBytes(String hexString) {        hexString = hexString.toUpperCase();        int length = hexString.length() / 2;        char[] hexChars = hexString.toCharArray();        byte[] b = new byte[length];        for (int i = 0; i < length; i++) {            int pos = i * 2;            b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));        }        return b;    }    private static byte charToByte(char c) {        return (byte) "0123456789ABCDEF".indexOf(c);    }    public static void main(String[] args) {        try {            // 金鑰必須是16的倍數            byte key[] = "8711110000222278".getBytes("utf-8");            String src = "183222222222";            System.out.println("金鑰:"+byteToHexString(key));            System.out.println("原字串:"+src);            String enc = byteToHexString(encrypt(src));            System.out.println("加密:"+enc);            System.out.println("解密:"+new String(decrypt(enc), "utf-8"));        } 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();        }    }}

後端輸出結果:

金鑰:38373134313330303030333134313738原字串:你好偏移量:30313233343536373839414243444546加密:08e56adf28a16558631aa0914d04bd0c偏移量:30313233343536373839414243444546解密:你好
3f3c4c79286b11ef59b0eac54c34d145.png

需要注意,後端輸出的金鑰和偏移量都要給前端,這樣解析出來的引數才是一致的,其中後端打印出的金鑰對應前端的key,後端打印出的便宜量對應前端的iv中的值!

表達可能不太清楚,除錯中有問題可私信我!