您的位置 首页 java

AES前后端对称加密

概述

高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法,对称加密算法即加密和解密的过程使用同一个秘钥进行加密。本文从实用的角度去描述前后端使用AES对称加密。

需求分析

前端请求数据传递参数时,需要对其进行加密,而不是使用明文进行传输,防止http请求被人截获而获取到信息,AES对称加密就是一种方式,前端对密码进行加密,传输给后端,后端获取之后使用和前端约定好的秘钥进行解密。

前端AES加解密

前端加密需要引入crypto-js的js文件,crypto-js是加密标准的JavaScript库,实现了各种加密算法,下载地址: # 《前后端加密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.get byte s("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
解密:你好  

需要注意,后端输出的密钥和偏移量都要给前端,这样解析出来的参数才是一致的,其中后端打印出的密钥对应前端的key,后端打印出的便宜量对应前端的iv中的值!

表达可能不太清楚,调试中有问题可私信我!

文章来源:智云一二三科技

文章标题:AES前后端对称加密

文章地址:https://www.zhihuclub.com/196667.shtml

关于作者: 智云科技

热门文章

网站地图