当前位置: 首页 > news >正文

Vue前端服务加密后端服务解密--AES算法实现

在实际项目中考虑到用户数据的安全性,在用户登录时,前端需要对用户密码加密(防止用户密码泄露),服务端收到登录请求时先对密码进行解密,然后再进行用户验证登操作。本文使用 AES ECB 模式算法来实现前端机密后端解密基本流程。

基本流程

  1. 用户在登录页输入用户信息,点击登录按钮时,前端需要对用户密码进行加密,再去请求登录接口,进行登录;
  2. 如果用户选择记住密码,注意cookie或localStorage中要保存加密后的密码,以防止密码泄露;
  3. 当用户再次回到登录页时(用户退出或令牌过期时),从cookie或localStorage中拿到加密密码要先解密然后初始化到密码框中;
  4. 服务端收到登录请求,先进行密码解密,然后再去验证用户的有效性;
  5. 或者先根据用户名去获取用户信息,然后对该用户密码加密,再去跟前端传的密码比对,以验证密码的有效性。

后端加密算法

pom.xml 引入

<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.56</version>
</dependency><!-- fastjson2 -->
<dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.51</version>
</dependency>

AES 工具类

package com.angel.ocean.util;import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import java.security.Security;
import java.util.Objects;@Slf4j
public class AESUtil {// AES 秘钥private static final String key = "5JKRGV0QO4WK1WCWVK55YEU0A1NPOXOP";private AESUtil() {}/*** AES 加密*/public static String encrypt(Object content) throws Exception {String data = "";if(null == content) {return null;}// 判断content是否为字符串if (content instanceof String) {data = content.toString();} else {data = JSON.toJSONString(content);}// 将加密过的byte[]数据转换成Base64编码字符串return base64ToString(aesECBEncrypt(data.getBytes(), key.getBytes()));}/*** AES解密*/public static Object decrypt(String content) {if(null == content) {return null;}try {byte[] base64 = stringToBase64(content);byte[] bytes = aesECBDecrypt(base64, key.getBytes());String result = new String(bytes);String data = result.replaceAll("\"", "");// 判断解密出来的数据是字符串还是jsonif (data.startsWith("{") && data.endsWith("}")) {return JSON.parse(data);} else {return data;}} catch (Exception e) {log.error("AESUtil.decrypt() error, {}", e.getMessage(), e);}return null;}private static byte[] aesECBEncrypt (byte[] content, byte[] keyBytes) {try {SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");cipher.init(Cipher.ENCRYPT_MODE, key);return cipher.doFinal(content);} catch (Exception e) {log.error("AESUtil.aesECBEncrypt() error, {}", e.getMessage(), e);}return null;}private static byte[] aesECBDecrypt(byte[] content, byte[] keyBytes) {try {SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");cipher.init(Cipher.DECRYPT_MODE, key);return cipher.doFinal(content);} catch (Exception e) {log.error("AESUtil.aesECBDecrypt() error, {}", e.getMessage(), e);}return null;}/*** 将字符串转换成Base64*/public static byte[] stringToBase64(String key) throws Exception {return Base64.decodeBase64(key.getBytes());}/*** 将Base64转换成字符串*/public static String base64ToString(byte[] key) throws Exception {return new Base64().encodeToString(key);}public static void main(String[] args) throws Exception {// 明文String data = "123456";// 加密String encryptData = encrypt(data);log.info("encryptData: {}", encryptData);// 解密String decryptData = Objects.requireNonNull(decrypt(encryptData)).toString();log.info("decryptData: {}", decryptData);}
}

main运行结果
在这里插入图片描述

Vue前端加密

安装crypto-js

npm install crypto-js

引入crypto-js

import CryptoJS from 'crypto-js'

AES 秘钥

const key = '5JKRGV0QO4WK1WCWVK55YEU0A1NPOXOP'

加密解密方法

methods: {encrypt (data) {var secretKey = CryptoJS.enc.Utf8.parse(key);var srcs = CryptoJS.enc.Utf8.parse(data);var encrypted = CryptoJS.AES.encrypt(srcs, secretKey, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});return encrypted.toString();},decrypt(data) {var secretKey = CryptoJS.enc.Utf8.parse(key);var decrypt = CryptoJS.AES.decrypt(data, secretKey, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});return CryptoJS.enc.Utf8.stringify(decrypt).toString();}
}

密码:123456,加密后的密码截图:
在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 数字信号处理3:数字滤波器设计
  • docker部署rabbitMQ
  • 用Python实现特征工程之特征变换——数值特征的归一化和标准化、类别特征的编码、特征组合和分解、特征缩放
  • 谈谈docker的四种网络模式
  • JavaDS —— 位图(BitSet)与 布隆过滤器
  • 数据结构总体概述
  • 三大科技看点引领奥运新风潮,你是否准备好迎接科技的未来?
  • write_sdc和write_script区别
  • 【gcc】基于gpt和python的流程和延迟梯度分析
  • C语言典型例题31
  • EXPLAIN和ANALYZE
  • PostgreSQL JSON 字段操作指南
  • JavaWeb——CSS的使用
  • 【Python第三方库】Requests全面解析
  • C++ | Leetcode C++题解之第332题重新安排行程
  • [Vue CLI 3] 配置解析之 css.extract
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • canvas 高仿 Apple Watch 表盘
  • HashMap剖析之内部结构
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • JS基础之数据类型、对象、原型、原型链、继承
  • JS实现简单的MVC模式开发小游戏
  • JS字符串转数字方法总结
  • leetcode-27. Remove Element
  • Mac转Windows的拯救指南
  • Mithril.js 入门介绍
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • Vue.js源码(2):初探List Rendering
  • Windows Containers 大冒险: 容器网络
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 浏览器缓存机制分析
  • 前嗅ForeSpider教程:创建模板
  • 什么是Javascript函数节流?
  • 由插件封装引出的一丢丢思考
  • 做一名精致的JavaScripter 01:JavaScript简介
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #数据结构 笔记三
  • $.each()与$(selector).each()
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (第27天)Oracle 数据泵转换分区表
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (篇九)MySQL常用内置函数
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转)shell中括号的特殊用法 linux if多条件判断
  • (轉)JSON.stringify 语法实例讲解
  • (轉貼) UML中文FAQ (OO) (UML)
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】