AES数据传输的加解密
- (一)AES加密算法原理:
- (二)举例说明:
(一)AES加密算法原理:
AES是作为DES的替代标准出现的,全称Advanced Encryption Standard,即:高级加密标准。AES加密算法,经历了公开的选拔,最终2000年,由比利时密码学家Joan Daemen和Vincent Rijmen设计的Rijndael算法被选中,成为了AES标准。
AES明文分组长度为128位,即16个字节,密钥长度可以为16个字节、24个字节、或32
个字节,即128位密钥、192位密钥、或256位密钥。
一、AES是对称加密算法:对称加密算法就是加解密使用的是相同的密钥。
AesUtils是前后端数据传输加密工具类,加解密的算法注入方式采用:AES/CBC/PKCS5Padding(算法/模式/补码方式)使用CBC模式,需要一个向量IV,可增加加密算法的强度
CBC模式优点:不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
(二)举例说明:
首先在vue的项目安装crypto-js:
在项目根目录下cmd输入命令:npm install crypto-js --save-dev
1、前台vue页面:HelloWorld.vue
<!--加解密-->
<!--eslint-disable -->
<template>
<div>
原数据:
<input v-model="userName" placeholder="请输入账号"></input>
<input v-model="password" placeholder="请输入密码"></input>
<button type="primary" @click="jiami" plain>加密</button>
<button type="primary" @click="jiemi" plain>解密</button>
加密数据:
<button type="primary" @click="tijiao" plain>提交</button>
</div>
</template>
<script>
import {Decrypt, Encrypt } from '@/encryption/index'
export default {
data() {
return {
userName: '',
password: '',
name:''
}
},
methods: {
tijiao(){
let formLogins = {
userName:this.userName,
password:this.password
}
var obj = JSON.stringify(formLogins)
let dd = Encrypt(obj)
console.log(formLogins)
console.log(obj)
this.$http.post('http://localhost:8084/testAesEncrypt',dd,{
headers:{
'Content-Type': 'application/json;charset=UTF-8',
}
})
.then((res)=>{
console.log(res);
alert(res.data)
let resData = Decrypt(res.data)
console.log("解密-----",resData);
alert(resData);
console.log(resData)
console.log(resData.name)
console.log(resData.pass)
// console.log(formLogins)
})
.catch(function (error) { // 请求失败处理
console.log(error);
});
},
jiami() {
console.log("加密-----", this.d1);
let dd = Encrypt(this.d1)
console.log(dd)
this.d2 = dd
},
jiemi() {
console.log("解密-----", this.d2);
this.d1 = Decrypt(this.d2)
},
}
}
</script>
2、index.js
import CryptoJS from 'crypto-js/crypto-js'
// 默认的 KEY 与 iv key需要为16位,key和iv可以一样
const KEY = CryptoJS.enc.Utf8.parse("G900o50M9FtX3Ci5");
const IV = CryptoJS.enc.Utf8.parse("39bas2G2Pj1q05gl");
/**
* AES加密 :字符串 key iv 返回base64
*/
export function Encrypt(word, keyStr, ivStr) {
let key = KEY
let iv = IV
if (keyStr) {
key = CryptoJS.enc.Utf8.parse(keyStr);
iv = CryptoJS.enc.Utf8.parse(ivStr);
}
let srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// console.log("-=-=-=-", encrypted.ciphertext)
return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
}
/**
* AES 解密 :字符串 key iv 返回base64
*
*/
export function Decrypt(word, keyStr, ivStr) {
let key = KEY
let iv = IV
if (keyStr) {
key = CryptoJS.enc.Utf8.parse(keyStr);
iv = CryptoJS.enc.Utf8.parse(ivStr);
}
let base64 = CryptoJS.enc.Base64.parse(word);
let src = CryptoJS.enc.Base64.stringify(base64);
var decrypt = CryptoJS.AES.decrypt(src, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
3、解决跨域请求的类、
package com.example.demo123.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* 解决跨域请求的
*/
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 你需要跨域的地址 注意这里的 127.0.0.1 != localhost
// * 表示对所有的地址都可以访问
corsConfiguration.addAllowedOrigin("http://localhost:8080");
// 跨域的请求头
corsConfiguration.addAllowedHeader("*");
// 跨域的请求方法
corsConfiguration.addAllowedMethod("*");
//加上了这一句,大致意思是可以携带 cookie
//最终的结果是可以 在跨域请求的时候获取同一个 session
corsConfiguration.setAllowCredentials(true);
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//配置 可以访问的地址
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}
4、加解密工具类、
package com.example.demo123.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AESUtils {
/**
* 加密AES算法
* @param data
* @param key
* @param iv
* @return
* @throws Exception
*/
public static String encrypt(String data, String key, String iv) throws Exception {
try {
//"算法/模式/补码方式"PKCS5Padding
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
int blockSize = cipher.getBlockSize();
byte[] dataBytes = data.getBytes();
int plaintextLength = dataBytes.length;
if (plaintextLength % blockSize != 0) {
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
}
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
//此处使用BASE64做转码功能,同时能起到2次加密的作用。
return new Base64().encodeToString(encrypted);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 解密算法
* @param data
* @param key
* @param iv
* @return
* @throws Exception
*/
public static String desEncrypt(String data, String key, String iv) throws Exception {
try {
byte[] encrypted1 = new Base64().decode(data);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original);
return originalString;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
5、数据测试类、
package com.example.demo123.controller;
import com.example.demo123.util.AESUtils;
import org.springframework.beans.factory.annotation.Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.security.SecureRandom;
import java.util.Random;
/**
* 〈一句话功能简述〉<br>
* 〈测试加解密和谷歌验证〉
*
* @author 44637
* @create 2018/10/24
* @since 1.0.0
*/
@Controller
public class TestController {
private static final Logger logger = LoggerFactory.getLogger(TestController.class);
@Value("${aes.key}")
private String AES_KEY;
@Value("${aes.iv}")
private String AES_IV;
@RequestMapping("/testAesEncrypt")
@ResponseBody
public String testAesEncrypt1(@RequestBody String map) throws Exception {
System.out.println(map);
String encryptData = AESUtils.desEncrypt(map, AES_KEY, AES_IV);
System.out.println(encryptData.toString());
String one= AESUtils.encrypt(encryptData, AES_KEY, AES_IV);
return one;
}
}