vue与java对称加密aes
AES加密解密:http://tool.chacuo.net/cryptaes
在数字加密算法中,通过可划分为对称加密和非对称加密
对称加密:如AES,DES,3DES
含义:加密和解密使用的是同一把钥匙。密钥不能在网络中传输,避免被拦截。如果要传输,必须要对密钥进行非对称加密再加密一次。
优点:算法简单,加密解密容易,效率高,执行快。
缺点:相对来说不算特别安全,只有一把钥匙,密文如果被拦截,且密钥也被劫持,那么,信息很容易被破译。
非对称加密:如RSA DSA RCC
含义:有两个钥匙,及公钥(Public Key)和私钥(Private Key)。公钥和私钥是成对的存在,如果对原文使用公钥加密,则只能使用对应的私钥才能解密。通过私钥经过一系列算法是可以推导出公钥的,但是无法通过公钥反向推倒出私钥,这个过程的单向的。
优点:安全,即使密文被拦截、公钥被获取,但是无法获取到私钥,也就无法破译密文。作为接收方,务必要保管好自己的密钥。
缺点:加密算法及其复杂,安全性依赖算法与密钥,而且加密和解密效率很低。
下载crypto-js cnpm i -S crypto-js
局部引用
import CryptoJS from "crypto-js";
工具类 const CryptoUtil = require('crypto-js') //约定密钥(与后端密钥保持一致) let key = CryptoUtil.enc.Utf8.parse("fc6cb28893f45be0");// 密钥16位长度字符 内容可自定义 let IV = CryptoUtil.enc.Utf8.parse("fc6cb28893f45be0");// 密钥偏移量 16位长度字符 /** * AES对称加密 (CBC模式,需要偏移量) * @param {Object} params 明文参数 */ export function encrypt(params){ //明文参数 let str = CryptoUtil.enc.Utf8.parse(params); //加密 let encryptedData = CryptoUtil.AES.encrypt(str, key, { iv:IV, mode: CryptoUtil.mode.CBC, //AES加密模式 padding: CryptoUtil.pad.Pkcs7 //填充方式 }); console.log("加密前:"+params);//加密前:QWEASDZXC console.log("加密后:"+encryptedData);//加密后:vlgQpBdfVvMplxwOTjxSyQ== return CryptoUtil.enc.Base64.stringify(encryptedData.ciphertext); //返回base64格式密文 } /** * AES对称解密 * @param {Object} params 加密参数 */ export function decrypt(params){ //base64格式密文转换 let base64 = CryptoUtil.enc.Base64.parse(params); let str = CryptoUtil.enc.Base64.stringify(base64); //解密 let decryptedData = CryptoUtil.AES.decrypt(str, key, { iv:IV, mode: CryptoUtil.mode.CBC, //AES加密模式 padding: CryptoUtil.pad.Pkcs7 //填充方式 }); console.log("解密前:"+params);//解密前:vlgQpBdfVvMplxwOTjxSyQ== console.log("解密后:"+CryptoUtil.enc.Utf8.stringify(decryptedData).toString());//解密后:QWEASDZXC return CryptoUtil.enc.Utf8.stringify(decryptedData).toString(); //返回明文 }
前台引用
import {encrypt,decrypt} from "@/utils/crypto-util";
后台 package com.teaIndustry.utils; import com.sun.org.apache.xml.internal.security.utils.Base64; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; /** * AES加密,key的大小必须是16个字节 * 如果没有指定分组密码模式和填充模式,ECB/PKCS5Padding就是默认值 * 如果没有指定分组密码模式为CBC,必须指定初始向量(iv),初始向量中密钥的长度必须是16个字节 * NoPadding模式,原文的长度必须是16个字节的整倍数 * @author km * @date 2022/06/28 */ public class AesUtils { //获取Cipher对象的算法 private static String transformation = "AES/CBC/PKCS5Padding"; /** * 加密 * @param input 明文 * @param key 密钥(AES,密钥的长度必须是16个字节) * @param algorithm 获取密钥的算法 * @return 返回密文 * @throws Exception */ public static String encrypt(String input, String key, String algorithm) throws Exception { // 1,获取Cipher对象 Cipher cipher = Cipher.getInstance(transformation); // 指定密钥规则 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 2.初始化向量的秘钥长度需要根据算法而定,des 8个字节长度 aes 16个字节长度 //这里为了方便,统一使用传来的秘钥 IvParameterSpec iv = new IvParameterSpec(key.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, sks, iv); // cipher.init(Cipher.ENCRYPT_MODE, sks); // 3. 加密 byte[] bytes = cipher.doFinal(input.getBytes()); // 对数据进行Base64编码 String encode = Base64.encode(bytes); return encode; } /** * 解密 * @param input 密文 * @param key 密钥(AES,密钥的长度必须是16个字节) * @param algorithm 获取密钥的算法 * @return 返回原文 * @throws Exception */ public static String decrypt(String input, String key, String algorithm) throws Exception { Cipher cipher = Cipher.getInstance(transformation); SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); IvParameterSpec iv = new IvParameterSpec(key.getBytes()); cipher.init(Cipher.DECRYPT_MODE, sks, iv); // cipher.init(Cipher.DECRYPT_MODE, sks); byte[] bytes = cipher.doFinal(Base64.decode(input)); return new String(bytes); } //测试 public static void main(String[] args) { String params = "QWEASDZXC"; String key = "qP2$bG9;vA0^uW0:"; // 约定的秘钥 String sf = "AES"; System.out.println("加密前字符串:"+params);//QWEASDZXC try { //加密 String jiami = encrypt(params,key,sf); System.out.println("加密后字符串:"+jiami);//vlgQpBdfVvMplxwOTjxSyQ== //解密 String jiemi = decrypt(jiami,key,sf); System.out.println("解密后字符串:"+jiemi);//QWEASDZXC } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }