前端登陆加密解决方案

news2024/11/29 0:36:06

项目背景

环食药烟草的数据下载模块中,需要判断用户在进行数据下载时是进行了登录操作,如果没有登录要跳转登陆页面,输入账号和密码进行登录。

使用场景

项目中需要前端书写登录页面,用户输入账号密码,前端获取到用户输入的账号密码做登陆操作时需要采用对密码做加密处理。

解决方案

前端通过使用CryptoJS库进行加密处理。CryptoJS库是一种常用的前端加密库,支持多种加密方式,常用的加密方式有:

  1. AES:高级加密标准,目前最常用的对称加密算法之一。可以使用128位、192位或256位密钥进行加密
  2. DES:数据加密标准,一种较早的对称加密算法。可以使用56位密钥进行加密
  3. TripleDES:三重数据加密标准,基于DES算法的一个更安全的版本,可以使用112位或168位密钥进行加密
  4. MD5:消息摘要算法,一种单向哈希函数,常用于对密码进行加密和验证
  5. SHA:安全散列算法,类似于MD5,但更安全,可以使用不同的位数(如SHA-256、SHA-384、SHA-512)进行加密
  6. HMAC:基于哈希函数的消息认证码算法,用于验证数据完整性和真实性

使用指南

  • 使用 npm或者yarn 安装 crypto-js

    npm install crypto-js –save
    yarn add crypto-js
    
  • 在 main.js 引入

    import CryptoJS from “crypto-js”;
    
    Vue.prototype.cryptoJS = CryptoJS;
    
  • 在 App.vue 使用

    export default {
    	mounted() {
    		console.log('this.cryptoJS', this.cryptoJS)
    	}
    }
    

    控制台打印内容如下:
    在这里插入图片描述

    说明安装成功,可以在项目中正常使用了~

    可以看出来 crypto-js 库的加密算法有很多。环食药烟草数据下载模块中采用的是 SHA256加密算法SHA256 是一种单向加密算法,意味着对于给定的哈希值,无法通过解密算法直接还原出原始数据。SHA256 算法是不可逆的,这也是其安全性的基础之一,目前没有已知的有效方法可以快速破解它。

  • SHA256算法加密

    const password = 'hello world';
    const res = this.cryptoJS.SHA256(password);
    const plainRes = res.toString(); // 加密的结果
    console.log('password 加密的结果是:', plainRes); // 
    
  • 前后端判断逻辑

    1. 用户输入账号密码
    2. 前端对密码进行 SHA256 算法加密密码
    3. 后端将前端传入的已加密的密码存入数据库
    4. 用户再次登录时根据前端传入的已加密的密码与数据库中存入的密码进行比较,一致说明密码正确;否则错误

其他常用加密算法使用指南

  • AES加密

    // AES 加密
    decrypt(word, key, iv) {
      let srcs = this.cryptoJS.enc.Utf8.parse(word);
      const AES_JM_RES = this.cryptoJS.AES.encrypt(srcs, key, {
        // 对称加密算法主要有AES、DES、3DES / 非对称加密算法主要有RSA、DSA、RCC
        // iv(初始变量)
        // key(加密密钥)
        // mode(加密模式 主要有CBC(默认)、CFB、CTR、OFB、ECB)
        // padding(填充方式 主要有Pkcs7(默认)、Iso97971、AnsiX923、Iso10126、ZeroPadding)
        iv: iv,
        mode: this.cryptoJS.mode.CBC, // 选择模式为CBC
        padding: this.cryptoJS.pad.Pkcs7 // 选择填充方式为PKCS7
      });
      let encryptedBase64Data = this.cryptoJS.enc.Base64.stringify(AES_JM_RES.ciphertext);
      return encodeURIComponent(encryptedBase64Data);
    }
    // AES 解密
    encrypt(word, key, iv) {
      word = decodeURIComponent(word);
      let encryptedHexStr = this.cryptoJS.enc.Base64.parse(word);
      let srcs = this.cryptoJS.enc.Base64.stringify(encryptedHexStr);
      let decrypt = this.cryptoJS.AES.decrypt(srcs, key,
        {
          iv: iv,
          mode: this.cryptoJS.mode.CBC,
          padding: this.cryptoJS.pad.Pkcs7,
        }
      );
      let decryptedStr = decrypt.toString(this.cryptoJS.enc.Utf8);
      return decryptedStr.toString();
    }
    
    // 样例
    const password = 'hello world';
    // 定义加密所需的参数
    const key = this.cryptoJS.enc.Utf8.parse('1234567890abcdef'); // 设置密钥为16字节长度的十六进制字符串
    const iv = this.cryptoJS.enc.Utf8.parse('abcdefghijklmnop'); // 初始化向量也必须是16字节长度的十六进制字符串
    const str = this.decrypt(password, key, iv);
    console.log('加密结果', str);
    const str1 = this.encrypt(str, key, iv);
    console.log('解密结果', str1);
    
  • DES加密

    const password = 'hello world';
    const key = this.cryptoJS.enc.Utf8.parse('123456789');
    const data = this.cryptoJS.enc.Utf8.parse(password);
    // DES 加密
    const encrypted = this.cryptoJS.DES.encrypt(data, key, {
      mode: this.cryptoJS.mode.ECB, // 选择模式为ECB
      padding: this.cryptoJS.pad.Pkcs7 // 选择填充方式为PKCS7
    });
    console.log('DES 加密结果:', encrypted.toString()); // KNugLrX23UddguNoHIO7dw==
    // DES 解密
    const decrypted = this.cryptoJS.DES.decrypt(encrypted, key, {
      mode: this.cryptoJS.mode.ECB, // 选择模式为ECB
      padding: this.cryptoJS.pad.Pkcs7 // 选择填充方式为PKCS7
    });
    console.log('DES 解密结果:', decrypted.toString(this.cryptoJS.enc.Utf8)); // hello world
    
  • MD5加密

    const password = 'hello world';
    const md5Res = this.cryptoJS.MD5(password).toString();
    console.log('password 加密的结果是:', md5Res); // 5eb63bbbe01eeed093cb22bb8f5acdc3
    
  • HMAC加密

    // 示例中采用HMAC-SHA256算法对数据进行加密
    // HMAC并不是一个加密算法,它是一种用于消息认证的技术,因此并不能进行解密操作
    const password = 'hello world';
    const key = this.cryptoJS.enc.Utf8.parse('123456789');
    // 计算 HMAC 
    const hmac = this.cryptoJS.HmacSHA256(password, key);
    console.log('HMAC加密结果:', hmac.toString()); // 9da40d794b56b945a8e382216b9778216326dd187f6b37e921ec28b63a09bdb0
    
  • TripleDES加密

    // 1. 在CryptoJS中,采用WordArray类型来传递数据,简单理解就是words是一个byte数组
    // 2. WordArray的这个对象具有toString()方法,所以在js中是可以直接隐式转换成字符串的,**但是默认是Hex编码(16进制)**
    // 3. 对称解密使用的算法是 `AES-128-CBC`算法,数据采用 `PKCS#7` 填充 , 因此这里的 `key` 需要为16位!
    
    const password = 'hello world';
    // 16位十六进制数作为密钥和密钥偏移量
    const key = this.cryptoJS.enc.Utf8.parse('0123456789abcdef'); // 密钥
    const data = this.cryptoJS.enc.Utf8.parse(password);
    // 定义向量(可选参数,如果不指定则会自动生成)
    const iv = this.cryptoJS.enc.Utf8.parse('abcdefghijklmnop'); // 偏移量
    // TripleDES 加密
    const encrypted = this.cryptoJS.TripleDES.encrypt(data, key, {
      iv: iv,
      mode: this.cryptoJS.mode.CBC, // 选择模式为CBC
      padding: this.cryptoJS.pad.Pkcs7 // 选择填充方式为PKCS7
    });
    console.log('TripleDES 加密结果是:', encrypted.toString()); // sEdwNwrfNcMrMj11iMjKdA==
    const decrypted = this.cryptoJS.TripleDES.decrypt(encrypted, key, {
      iv: iv,
      mode: this.cryptoJS.mode.CBC, // 选择模式为CBC
      padding: this.cryptoJS.pad.Pkcs7 // 选择填充方式为PKCS7
    });
    console.log('TripleDES 解密结果:', decrypted.toString(this.cryptoJS.enc.Utf8)); // hello world
    
  • Base64加密
    Base64顾名思义,就是基于64个可打印字符来表示二进制数据的一种方法,「注意它并不是一种加密算法」。对于64个打印字符,我们只需要6个二进制位就可以完全表示了。那么我们如何利用8个二进制位来表示只需要6个二进制位就可以完全表示的可打印字符呢?由于2的6次方等于64,所以我们可以将每6个位元为一个单元,对应某个可打印字符。三个字节有24个位元,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。

    // 原生加密
    const btoa = window.btoa('hello, world')  // 编码
    console.log('加密后',btoa) // aGVsbG8sIHdvcmxk
    const atob = window.atob('aGVsbG8sIHdvcmxk')  // 解码
    console.log('解密后',atob) // hello, world
    
    // base64插件
    npm install --save js-base64 // 安装
    
    // 使用
    import { Base64 } from 'js-base64';
    
    const encode = Base64.encode('hello, my name is FuChaoyang'); // 编码
    console.log('插件加密后', encode);
    const decode = Base64.decode('aGVsbG8sIG15IG5hbWUgaXMgRnVDaGFveWFuZyA'); // 解码
    console.log('插件解密后', decode);
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1432530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Allegro中设置让Route Keepout(禁止布线区)允许布线或打过孔的方法

Allegro中设置让Route Keepout(禁止布线区)允许布线或打过孔的方法 Chapter1 Allegro中设置让Route Keepout(禁止布线区)允许布线或打过孔的方法一、前言二、设置方法 Chapter2 Cadence Allegro PCB设计88问解析(二十三) 之 Alleg…

QT中QComboBox添加点击事件,实现下拉框自动刷新

因为项目需要,在QT中的ui界面添加QComboBox控件,需求是实现控件的点击事件,查了资料,发现这个控件类的本身是没有点击信号可以使用的。 但是QT是基于C的面向对象,有了这个特点,我们就可以继承原来的类&…

认识Tomcat (一)

认识Tomcat (一) 一、服务器 1.1 服务器简介 ​ 硬件服务器的构成与一般的PC比较相似,但是服务器在稳定性、安全性、性能等方面都要求更高,因为CPU、芯片组、内存、磁盘系统、网络等硬件和普通PC有所不同。 ​ 软件服务器&…

Docker 搭建mysql 集群(二)

PXC方案 很明显 PXC方案在任何一个节点写入的数据都会同步到其他节点,数据双向同步的(在任何节点上都可以同时读写) 创建MySQL PXC集群 1 安装PXC镜像 docker pull percona/percona-xtradb-cluster:5.7.21 2 为PXC镜像改名 docker tag pe…

从零开始手写mmo游戏从框架到爆炸(三)— 服务启动接口与网络事件监听器

上一章我们完成了netty服务启动的相关抽象(https://blog.csdn.net/money9sun/article/details/136025471),这一章我们再新增一个全局的服务启动类,方便后续扩展。 服务启动 新增的两个类如下: 定义一个接口IServer …

react native错误记录

第一次运行到安卓失败 Could not find implementation class com.facebook.react.ReactRootProjectPlugin for plugin com.facebook.react.rootproject specified in jar:file:/D:/Android_Studio_Data/.gradle/caches/jars-9/o_3a1fd35320f05989063e7069031b710f/react-nativ…

Linux命令·

debian linux: deb 软件包 deb软件包分为两种,.deb二进制软件包,.dsc源码包 软件包的两种管理工具 1.dpkg 软件包软件的安装包必须存在 不能从镜像点获得安装包 不能检测软件之间的依赖关系 dpkg -i package.deb #安装包 dpkg -r package …

Elasticsearch:使用 Inference API 进行语义搜索

在我之前的文章 “Elastic Search 8.12:让 Lucene 更快,让开发人员更快”,我有提到 Inference API。这些功能的核心部分始终是灵活的第三方模型管理,使客户能够利用当今市场上下载最多的向量数据库及其选择的转换器模型。在今天的…

SpringBoot 登录检验JWT令牌 生成与校验

JWT官网 https://jwt.io/ 引入依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version> </dependency>设置过期时间 LocalDateTime localDateTime LocalDateTime.now().…

uniapp中使用EelementPlus

uniapp的强大是非常震撼的&#xff0c;一套代码可以编写到十几个平台。这个可以在官网上进行查询uni-app官网。主要还是开发小型的软件系统&#xff0c;使用起来非常的方便、快捷、高效。 uniapp中有很多自带的UI&#xff0c;在创建项目的时候&#xff0c;就可以自由选择。而E…

React Native学习记录

一、创建RN项目的时候是空文件夹的问题 1.使用npx react-native init RNDemos初始化项目的时候&#xff0c;会报错&#xff0c;模版错误&#xff0c;然后创建出来一个空的文件夹 2.如果出现这种情况&#xff0c;需要设置npm install -g react-native-cli 3.安装完成以后再次初…

python 多线程编程(一)

文章目录 threading - 基于线程的并行线程对象thread 类thread方法thread 属性例子 锁对象递归锁对象 条件对象 队列Queue对象SimpleQueque 对象例子 最近的工作需要用到多线程提升程序的运行效率&#xff0c;以前一直没有机会进行多线程编程&#xff0c;所以一直没有机会学习p…

QEMU源码全解析 —— 内存虚拟化(2)

接前一篇文章&#xff1a; 本文内容参考&#xff1a; 《趣谈Linux操作系统》 —— 刘超&#xff0c;极客时间 《QEMU/KVM》源码解析与应用 —— 李强&#xff0c;机械工业出版社 QEMU内存管理模型 特此致谢&#xff01; QEMU内存初始化 1. 基本结构 在开始介绍内存初始化…

[Python] 什么是KMeans聚类算法以及scikit-learn中的KMeans使用案例

什么是无监督学习&#xff1f; 无监督学习是机器学习中的一种方法&#xff0c;其主要目的是从无标签的数据集中发现隐藏的模式、结构或者规律。在无监督学习中&#xff0c;算法不依赖于任何先验的标签信息&#xff0c;而是根据数据本身的特征和规律进行学习和推断。无监督学习…

随机图论基础

一&#xff0c;随机图、随机图空间 1&#xff0c;随机图 一个n个点的无向图&#xff0c;最多有sn(n-1)/2条边。 每条边都有一定的概率存在&#xff0c;有一定概率不存在&#xff0c;那么每个图都有一个出现概率。 2&#xff0c;随机图空间 一共有2^s种不同的图&#xff0c…

STM32外部中断原理及应用

对于嵌入式系统开发者而言&#xff0c;STM32系列微控制器是一个强大而灵活的选择&#xff0c;而外部中断作为其中一项重要的功能&#xff0c;为实时响应外部事件提供了关键支持。本文将带领初学者深入理解STM32外部中断的原理和应用&#xff0c;让你能够轻松地在你的项目中使用…

Jvm FullGC 如何排查?

使用场景 我们在使用系统时&#xff0c;有时请求和响应会变得特别慢&#xff0c;系统也变得很卡。 有可能是FullGC的问题&#xff0c;可以逐步地进行排查。 使用jps和top确定进程号pid jps可以列出正在运行的jvm进程&#xff0c;并显示jvm执行主类名称( main()函数所在的类…

[Vue3]父子组件相互传值数据同步

简介 vue3中使用setup语法糖&#xff0c;父子组件之间相互传递数据及数据同步问题 文章目录 简介父传子props传递值 使用v-bind绑定props需要计算toRefcomputed emit传递方法 使用v-on绑定 子传父expose v-model总结 父传子 props传递值 使用v-bind绑定 父组件通过props给子…

第三百零七回

文章目录 1. 概念介绍2. 使用方法3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何在输入框中提示错误"相关的内容&#xff0c;本章回中将介绍如何在输入框中处理光标.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在使用TextField组件作为…

【RT-DETR有效改进】UNetv2提出的一种SDI多层次特征融合模块(细节高效涨点)

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 本问给大家带来的改进机制是UNetv2提出的一种多层次特征融合模块(SDI)其是一种用于替换Concat操作的模块,SDI模块的主要思想是通过整合编码器生成的层级特征图来增强图像中的语义信息和细节信息。包括皮肤…