前端CryptoJS加密、后端JAVA解密代码实现参考

 更新时间:2023年12月24日 08:51:48   投稿:WDC  
这篇文章主要介绍了前端CryptoJS加密、后端JAVA解密代码实现参考,需要的朋友可以参考下

前端的朋友可能会关注前端js加密,我们在做 WEB 的登录功能时一般是通过 Form 提交或 Ajax 方式提交到服务器进行验证的。为了防止抓包,登录密码肯定要先进行一次加密(RSA),再提交到服务器进行验证。

1、使用AES算法的CBC模式加密

1.1、前端加密代码实现参考

vue项目需要安装CryptoJS安装包,安装命令如下:

npm install crypto-js

在项目中引入CryptoJS

import CryptoJS from 'crypto-js'

参考代码如下:

<script>
     // 此处key为16进制
     let key = '385f33cb91484b04a177828829081ab7';
     console.log('密钥:', key);
     // key格式化处理
     key = CryptoJS.enc.Utf8.parse(key)
     // 偏移量长度为16位, 注:偏移量需要与后端定义好,保证一致
     let iv = "37fa77f6a3b0462d";
     iv = CryptoJS.enc.Utf8.parse("37fa77f6a3b0462d");
     // 加密内容
     const source = {
    	"username": "用户名",
    	"password": "密码",
    	"timestamp": new Date().getTime()
	}
	const content = JSON.stringify(source);
     console.log('加密前:', source);
     // 加密方法
     const encryptedContent = CryptoJS.AES.encrypt(content, key, {
         iv: iv,
         mode: CryptoJS.mode.CBC,  
         padding: CryptoJS.pad.Pkcs7
     })
     const encStr = encryptedContent.ciphertext.toString()
     console.log("加密后:", encStr);
     // 解密方法
     const decryptedContent = CryptoJS.AES.decrypt(CryptoJS.format.Hex.parse(encStr), key, {
         iv: iv,
         mode: CryptoJS.mode.CBC,  
         padding: CryptoJS.pad.Pkcs7
     })
     console.log('解密:',CryptoJS.enc.Utf8.stringify(decryptedContent));
</script>

前端打印结果

说明

1> CBC模式前、后端需要确定偏移量的值,并且保持一致,这样才能确保后端解密成功。

2> 前端CBC模式或者ECB模式下的填充方式 Pkcs7,对应后端AES算法模式中的 PKCS5Padding 填充方式

3> CryptoJS对应的API文档地址:https://cryptojs.gitbook.io/docs/#encoders

1.2、后端解密代码实现参考

后端代码实现需要引入的maven依赖如下:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

参考代码实现如下:

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
 
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
 
/**
 * AES对称加密工具类
 *
 * @author 星空流年
 */
public class AesUtil {
    /**
     * 偏移量
     *
     * 说明:偏移量字符串必须是16位 当模式是CBC的时候必须设置偏移量
     * 此处值与前端偏移量值保持一致
     */
    private static String iv = "37fa77f6a3b0462d";
 
    /**
     * 加密算法
     */
    private static String Algorithm = "AES";
 
    /**
     * 算法/模式/补码方式
     */
    private static String AlgorithmProvider = "AES/CBC/PKCS5Padding";
 
    /**
     * 加密
     *
     * @param src 加密内容
     * @param uniqueKey 加密key
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws InvalidAlgorithmParameterException
     * @throws UnsupportedEncodingException
     */
    public static String encrypt(String src, String uniqueKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, UnsupportedEncodingException {
        byte[] key = uniqueKey.getBytes();
        SecretKey secretKey = new SecretKeySpec(key, Algorithm);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
        Cipher cipher = Cipher.getInstance(AlgorithmProvider);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
        byte[] cipherBytes = cipher.doFinal(src.getBytes("UTF-8"));
        return byteToHexString(cipherBytes);
    }
 
    /**
     * 解密
     *
     * @param enc       加密内容
     * @param uniqueKey 唯一key
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     * @throws InvalidAlgorithmParameterException
     * @throws InvalidKeyException
     * @throws DecoderException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public static String decrypt(String enc, String uniqueKey) throws NoSuchPaddingException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidAlgorithmParameterException, InvalidKeyException, DecoderException, BadPaddingException, IllegalBlockSizeException {
        byte[] key = uniqueKey.getBytes();
        SecretKey secretKey = new SecretKeySpec(key, Algorithm);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
        Cipher cipher = Cipher.getInstance(AlgorithmProvider);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
        byte[] hexBytes = hexStringToBytes(enc);
        byte[] plainBytes = cipher.doFinal(hexBytes);
        return new String(plainBytes, "UTF-8");
    }
 
    /**
     * 将byte数组转换为16进制字符串
     *
     * @param src
     * @return
     */
    private static String byteToHexString(byte[] src) {
        return Hex.encodeHexString(src);
    }
 
    /**
     * 将16进制字符串转换为byte数组
     *
     * @param hexString
     * @return
     */
    private static byte[] hexStringToBytes(String hexString) throws DecoderException {
        return Hex.decodeHex(hexString);
    }
 
    /**
     * AES加密、解密测试方法
     *
     * @param args
     */
    public static void main(String[] args) {
        try {
            // 唯一key作为密钥
            String uniqueKey = "385f33cb91484b04a177828829081ab7";
            // 加密前数据,此处数据与前端数据一致(加密内容包含有时间戳),请注意查看前端加密前数据
            String src = "{\"username\":\"用户名\",\"password\":\"密码\",\"timestamp\":1628218094188}";
            System.out.println("密钥:" + uniqueKey);
            System.out.println("原字符串:" + src);
            // 加密
            String encrypt = encrypt(src, uniqueKey);
            System.out.println("加密:" + encrypt);
            // 解密
            String decrypt = decrypt(encrypt, uniqueKey);
            System.out.println("解密:" + decrypt);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

测试结果

2、使用AES算法的ECB模式加密

前面也说到,AES的ECB和CBC模式下的填充方式 Pkcs7,对应后端AES算法模式中的 PKCS5Padding 填充方式,只不过CBC模式需要添加偏移量,而ECB模式则不需要,大体实现方式本质上没有太大差别。

2.1、前端加密代码实现参考

vue项目需要安装CryptoJS安装包,安装命令如下:

npm install crypto-js

在项目中引入CryptoJS

import CryptoJS from 'crypto-js'

参考代码如下:

<script>
     // 此处key为16进制
     let key = '385f33cb91484b04a177828829081ab7';
     console.log('密钥:', key);
     // key格式化处理
     key = CryptoJS.enc.Utf8.parse(key)
	// 加密内容
     const source = {
    	"username": "用户名",
    	"password": "密码",
    	"timestamp": new Date().getTime()
	}
	const content = JSON.stringify(source);
     console.log('加密前:', source);
     // 加密方法
     const encryptedContent = CryptoJS.AES.encrypt(content, key, {
         mode: CryptoJS.mode.ECB,  
         padding: CryptoJS.pad.Pkcs7
     })
     const encStr = encryptedContent.ciphertext.toString()
     console.log('加密后:', encStr);
     // 解密方法
     const decryptedContent = CryptoJS.AES.decrypt(CryptoJS.format.Hex.parse(encStr), key, {
         mode: CryptoJS.mode.ECB,  
         padding: CryptoJS.pad.Pkcs7
     })
     console.log('解密:',CryptoJS.enc.Utf8.stringify(decryptedContent));
</script>

前端打印结果

2.2、后端加密代码实现参考

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
 
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
 
/**
 * AES对称加密工具类
 *
 * @author 星空流年
 */
public class AesUtil {
    /**
     * 加密算法
     */
    private static String Algorithm = "AES";
 
    /**
     * 算法/模式/补码方式
     */
    private static String AlgorithmProvider = "AES/ECB/PKCS5Padding";
 
    /**
     * 加密
     *
     * @param src       原内容
     * @param uniqueKey 唯一key
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws DecoderException
     */
    public static String encrypt(String src, String uniqueKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, DecoderException {
        byte[] key = uniqueKey.getBytes();
        SecretKey secretKey = new SecretKeySpec(key, Algorithm);
        Cipher cipher = Cipher.getInstance(AlgorithmProvider);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] cipherBytes = cipher.doFinal(src.getBytes(StandardCharsets.UTF_8));
        return byteToHexString(cipherBytes);
    }
 
    /**
     * 解密
     *
     * @param enc       加密内容
     * @param uniqueKey 唯一key
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     * @throws InvalidAlgorithmParameterException
     * @throws InvalidKeyException
     * @throws DecoderException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public static String decrypt(String enc, String uniqueKey) throws NoSuchPaddingException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidAlgorithmParameterException, InvalidKeyException, DecoderException, BadPaddingException, IllegalBlockSizeException {
        byte[] key = uniqueKey.getBytes();
        SecretKey secretKey = new SecretKeySpec(key, Algorithm);
        Cipher cipher = Cipher.getInstance(AlgorithmProvider);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] hexBytes = hexStringToBytes(enc);
        byte[] plainBytes = cipher.doFinal(hexBytes);
        return new String(plainBytes, SystemConstants.UTF_8);
    }
 
    /**
     * 将byte数组转换为16进制字符串
     *
     * @param src
     * @return
     */
    private static String byteToHexString(byte[] src) {
        return Hex.encodeHexString(src);
    }
 
    /**
     * 将16进制字符串转换为byte数组
     *
     * @param hexString
     * @return
     */
    private static byte[] hexStringToBytes(String hexString) throws DecoderException {
        return Hex.decodeHex(hexString);
    }
 
    /**
     * AES加密、解密测试方法
     *
     * @param args
     */
    public static void main(String[] args) {
        try {
            // 唯一key作为密钥
            String uniqueKey = "385f33cb91484b04a177828829081ab7";
            // 加密前数据,此处数据与前端数据一致(加密内容包含有时间戳),请注意查看前端加密前数据
            String src = "{\"username\":\"用户名\",\"password\":\"密码\",\"timestamp\":1628220492939}";
            System.out.println("密钥:" + uniqueKey);
            System.out.println("原字符串:" + src);
            // 加密
            String encrypt = encrypt(src, uniqueKey);
            System.out.println("加密:" + encrypt);
            // 解密
            String decrypt = decrypt(encrypt, uniqueKey);
            System.out.println("解密:" + decrypt);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

测试结果

到此这篇关于前端CryptoJS加密、后端解密代码实现参考的文章就介绍到这了,更多相关前端CryptoJS加密、后端解密代码实现参考内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • PHP 与 js的通信(via ajax,json)

    PHP 与 js的通信(via ajax,json)

    一定要设置xmlHttp.setRequestHeader,否则传往PHP的参数会变成null(line 38)
    2010-11-11
  • 微信小程序+云开发实现欢迎登录注册

    微信小程序+云开发实现欢迎登录注册

    这篇文章主要介绍了微信小程序+云开发实现欢迎登录注册,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • javascript将数组插入到另一个数组中的代码

    javascript将数组插入到另一个数组中的代码

    下面的代码主要功能就是将数组arr2插入到数组arr1的index位置,需要的朋友可以参考下
    2013-01-01
  • 微信小程序实现拍照打卡功能

    微信小程序实现拍照打卡功能

    这篇文章主要为大家详细介绍了微信小程序实现拍照打卡功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • JS小游戏之极速快跑源码详解

    JS小游戏之极速快跑源码详解

    这篇文章主要介绍了JS小游戏之极速快跑源码详解,对游戏的主要流程及原理进行了较为详细的讲解,并附有完整实例源码,需要的朋友可以参考下
    2014-09-09
  • Angularjs结合Bootstrap制作的一个TODO List

    Angularjs结合Bootstrap制作的一个TODO List

    这篇文章主要介绍了Angularjs结合Bootstrap制作的一个TODO List 的相关资料,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • webpack 5.68.0版本教程示例详解

    webpack 5.68.0版本教程示例详解

    这篇文章主要为大家介绍了webpack 5.68.0版本教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • 微信小程序input抖动问题的修复方法

    微信小程序input抖动问题的修复方法

    这篇文章主要给大家介绍了关于微信小程序input抖动问题的修复方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • js仿拉勾网首页穿墙广告效果

    js仿拉勾网首页穿墙广告效果

    本文主要介绍js仿拉勾网首页穿墙广告效果的实例,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • Uniapp如何封装网络请求方法demo

    Uniapp如何封装网络请求方法demo

    这篇文章主要为大家介绍了Uniapp如何封装网络请求方法demo,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10

最新评论