vue前端使用crypto字符串进行加密,传入后台使用springboot解密字符串-vue登录注册密码双重加密

前后端在参数传递的时候,不能将一些敏感的数据暴露出来,如果铭文传送的话就容易被拦截出来,所以我们需要在前端传递的时候进行加密,然后在后端进行解密。

尝试过MD5加密,但是后端解密的时候,需要按照前端加密的方式进行搞代码,这样太麻烦了。于是找了一个简单的解决办法。

前端使用crypto.js对字符串加密,然后后端引入crypto的Utils,直接通过设定的KEY进行解密,下面来看看如何实现。

前端部分

安装依赖

npm install crypto-js --save

在项目中新建utils文件夹,然后在这里面创建一个secret.js

vue前端使用crypto字符串进行加密,传入后台使用springboot解密字符串-vue登录注册密码双重加密-1

具体内容如下:

[collapse status="false" title="secret.js"]

import CryptoJS from 'crypto-js/crypto-js'
// 默认的 KEY 与 iv
const KEY = CryptoJS.enc.Utf8.parse('qwertyuiopasdf12') // ''中与后台一样  密码
const IV = CryptoJS.enc.Utf8.parse('qwertyuiopasdf12') // ''中与后台一样,
// qwertyuiopasdf12  可随意自己定义,但是必须满足十六位,必须与后台的一致
/**
 * AES加密 :字符串 key iv  返回base64
 */
export function encrypt(word) {
  const key = KEY
  const iv = IV
  const srcs = CryptoJS.enc.Utf8.parse(word)
  var encrypted = CryptoJS.AES.encrypt(srcs, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.ZeroPadding
  })
  return CryptoJS.enc.Base64.stringify(encrypted.ciphertext)
}
/**
 * AES 解密 :字符串 key iv  返回base64
 *
 */
export function decrypt(word) {
  const key = KEY
  const iv = IV
  const base64 = CryptoJS.enc.Base64.parse(word)
  const src = CryptoJS.enc.Base64.stringify(base64)
  var decrypt = CryptoJS.AES.decrypt(src, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.ZeroPadding
  })
  var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
  return decryptedStr.toString()
}

[/collapse]

自行修改const KEY 和 IV ,注意最好是16位

只要前后台保持一致就可以了。

引入使用

在需要加密的地方引入encrypt

import {encrypt,decrypt} from './utils/secret.js'
//或者
import {encrypt,decrypt} from '@/utils/secret.js'

如果你只需要加密,则只引入encrypt,decrypt是解密用的。

然后就可以加密字符串啦

//使用encrypt加密,后端再解密
this.bwsUser.password = encrypt(this.originalPassword);

后台部分

创建工具类

在后端utils的文件夹下创建AesEncryptUtil工具类

vue前端使用crypto字符串进行加密,传入后台使用springboot解密字符串-vue登录注册密码双重加密-2

具体内容如下:

[collapse status="false" title="AesEncryptUtil"]

package com.beiwangshan.blog.utils;
/**
 * 参数加解密工具类
 */
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AesEncryptUtil {
    // 使用AES-128-CBC加密模式,key需要为16位,key和iv可以相同!
    //密钥必须与前台的密钥保持一致
    private static String KEY = "qwertyuiopasdf12";
    private static String IV = "qwertyuiopasdf12";
    /**
     * 加密方法
     *
     * @param data 要加密的数据
     * @param key 加密key
     * @param iv 加密iv
     * @return 加密的结果
     * @throws Exception
     */
    public static String encrypt(String data, String key, String iv) throws Exception
    {
        try
        {
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");// "算法/模式/补码方式"NoPadding PkcsPadding
            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);
            return new Base64().encodeToString(encrypted);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 解密方法
     *
     * @param data 要解密的数据
     * @param key 解密key
     * @param iv 解密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/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);
            String originalString = new String(original);
            return originalString;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 使用默认的key和iv加密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static String encrypt(String data) throws Exception
    {
        return encrypt(data, KEY, IV);
    }
    /**
     * 使用默认的key和iv解密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static String desEncrypt(String data) throws Exception
    {
        return desEncrypt(data, KEY, IV);
    }
}

[/collapse]

使用

因为工具类中都是静态方法,所以可以直接使用,但是需要进行异常处理,具体代码如下:

try {
    String realPassword =  = AesEncryptUtil.desEncrypt(bwsUser.getPassword());
}catch (Exception e){
    e.printStackTrace();
}

注意:

如果你传输的字符串,不够十六位,解密之后,会使用空字符串进行补位,你需要在解密之后,对字符串进行去空字符串操作如下

realPassword.trim()

建议直接添加trim()使用。

例如我的:

boolean matches = bCryptPasswordEncoder.matches(realPassword.trim(), userFromDb.getPassword());
if (!matches) {
   return ResponseResult.FAILED("用户名或密码错误");
}

vue前端使用crypto字符串进行加密,传入后台使用springboot解密字符串-vue登录注册密码双重加密-3

© 版权声明
THE END
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容