Vue使用CryptoJS实现前后端密码加密

引用:https://www.jianshu.com/p/f9284c3f732c

https://blog.csdn.net/qq_46673413/article/details/136901184

一般管理系统前端传递密码,没有被加密过,就有安全问题,需要对前端进行加密,,

crypto.js

是一个javascript库,提供了一系列密码学函数和工具,用于加密,解密,生成摘要等任务,,他支持多种加密算法,包括常见的对称加密算法(如:AES,DES) 和非对称机密算法 RSA

同时,cryptoJs还包括了ECB和CBC两种模式,其中ECB模式: Electronic codebook 电码本,,在ECB模式中,每个明文分组都被单独加密,,且每个明文分组都被加密为相同的密文分组,也就是说,如果两个明文分组相同,那么他们的密文分组也相同,,CBC模式: cipher block chaining(密文分组链接模式),在cbc模式中,每个明文分组都是与前一个密文分组进行xor运算,,然后进行加密,,因此,密文分组是相互连接的,如果两个明文分组相同,那么他们的密文分组也会不同,

这里,我们使用了AES对称加密算法,并使用了CBC模式实现登录密码的加密,实现步骤如下:

前端使用CryptoJS
js 复制代码
npm install crypto-js
js 复制代码
import CryptoJS from 'crypto-js';

加密方法:

js 复制代码
//设置秘钥和秘钥偏移量
const SECRET_KEY = CryptoJS.enc.Utf8.parse("1234567890123456");
const SECRET_IV = CryptoJS.enc.Utf8.parse("1234567890123456");
/**
 * 加密方法
 * @param word
 * @returns {string}
 */
function encrypt(word) {
  let srcs = CryptoJS.enc.Utf8.parse(word);
  let encrypted = CryptoJS.AES.encrypt(srcs, SECRET_KEY, {
      iv: SECRET_IV ,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.ZeroPadding
  })
  return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
}

解密方法:

js 复制代码
function decrypt(word) {
  let base64  = CryptoJS.enc.Base64.parse(word);
  let srcs = CryptoJS.enc.Base64.stringify(base64);
  const decrypt = CryptoJS.AES.decrypt(srcs, SECRET_KEY, {
    iv: SECRET_IV ,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.ZeroPadding
  });
  const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  return decryptedStr;
}
java

java解密实现:

java 复制代码
package com.ruoyi.framework.config.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * @author cc
 * @date 2024-04-25 10:39
 **/

public class CryptoUtil {

    private final static String IV = "1234567890123456";//需要前端与后端配置一致
    private final static String KEY = "1234567890123456";


    /**
     * 解密算法,使用默认的IV,KEY
     * @param content
     * @return
     */
    public static String decrypt(String content){
        return decrypt(content,KEY,IV);
    }


    public static String encrypt(String content,String key,String iv){
        try{
            // "算法/模式/补码方式"NoPadding PkcsPadding
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            int blockSize = cipher.getBlockSize();
            byte[] dataBytes = content.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("UTF-8"), "AES");
            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes("UTF-8"));
            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
            byte[] encrypted = cipher.doFinal(plaintext);


            return  Base64.getEncoder().encodeToString(encrypted);
        }catch (Exception e) {
            throw new RuntimeException("加密算法异常 CryptoUtil encrypt()加密方法,异常信息:" + e.getMessage());
        }

    }


    /**
     * 解密方法
     * @param content
     * @param key
     * @param iv
     * @return
     */
    public static String decrypt(String content, String key, String iv){
        try {
            byte[] encrypted1 = Base64.getDecoder().decode(content);
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            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);
            return new String(original).trim();
        } catch (Exception e) {
            throw new RuntimeException("加密算法异常 CryptoUtil decrypt()解密方法,异常信息:" + e.getMessage());
        }
    }


    public static void main(String[] args) {
        String decrypt = CryptoUtil.decrypt("8lu4XRkZoVfn658E39KtNg==");
        System.out.println("decrypt = " + decrypt);
    }

}

不知道为什么必需使用,NoPadding 才不会报错,,应该是jdk有问题

将sprintsecurity的passwordEncoder换掉,

或者不用换,用之前的passwordEncoder ,,在对比密码之前将 前端加密的密码 ,解码还原回去

相关推荐
阿珊和她的猫2 分钟前
以用户为中心的前端性能指标解析
前端·javascript·css
木心术12 分钟前
OpenClaw网页前端开发与优化全流程指南
前端·人工智能
Amumu121383 分钟前
HTML5的新特性
前端·html·html5
SeSs IZED9 分钟前
【Nginx 】Nginx 部署前端 vue 项目
前端·vue.js·nginx
叫我一声阿雷吧17 分钟前
JS 入门通关手册(36):变量提升、暂时性死区与块级作用域
javascript·变量提升·暂时性死区·tdz·块级作用域· 前端面试
成都渲染101云渲染666620 分钟前
跳出“硬件堆砌”陷阱|渲染101如何用技术重构云渲染的专业价值?
java·前端·javascript
快乐点吧26 分钟前
【前端】前端开发中如何高效利用 curl 工具
前端·状态模式
橘子编程34 分钟前
OpenClaw(小龙虾)完整知识汇总
java·前端·spring boot·spring·spring cloud·html5
SuperEugene39 分钟前
Vue3 性能优化规范:日常必做优化(不玄学、可落地)|可维护性与兜底规范篇
开发语言·前端·javascript·vue.js·性能优化·前端框架
Binary-Jeff39 分钟前
Spring 创建 Bean 的关键流程
java·开发语言·前端·spring boot·后端·spring·学习方法