关于用aes在java后端发送加密URL到前端vue页面并解密

本文详细介绍了如何在Java后端使用javax.crypto包实现AES加密,包括使用16位密钥和偏移量,CBC/PKCS5Padding模式。同时,讨论了Base64编码在URL中的应用,以及如何通过encodeURIComponent方法处理+和/字符。还涉及了如何在前端使用crypto-js进行解密,强调了编码模式和密钥一致性的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java后端代码实现:使用javax.crypto包的功能,用16位的key和16位的偏移量,采用模式和补码方式为CBC/PKCS5Padding。

这里代码可参看参看:

Java 实现 AES 加密和解密完整示例_java aes加密-优快云博客

但返回值时将加密结果使用Base64再次编码,由于Base64编码可能出现+和/,可能会引起URL内部的混乱,故模仿js中的encodeURIComponent方法,将+和/转化,方法如下:

    /**
     * 对url字符串进行编码
     * @param url 待编码的url字符串
     * @return 编码后的字符串
     */
    public static String javaEncodeURIComponent(String url) {
        try {
            return URLEncoder.encode(url, "UTF-8").replace("+", "%20").replace("*", "%2A")
                    .replace("%7E", "~").replace("/", "%2F");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "";
        }
    }   

返回值的书写形式就会变成:

// 将密文转换为 Base64 编码字符串,再转换可用的,可被js识别的url字符串
return javaEncodeURIComponent(Base64.getEncoder().encodeToString(string));

此时URL中参数部分的内容就会变成类似乱码的形式:

http://*****************/?NOKPRN
0aKYVAOGhkds03XvU%2BjKEFqk0GQsLRa1lz0cyvYhn35EYSVInVo00oRiJxh%2BT%2B0vuF%2FJOEY7909KZ2WqJTb.b4ZQm3kDiiN66zDY%3D

发送给前端后,利用crypto-js进行解密,注意解密时使用的编码模式,key和偏移量都需要和后端保持一致,否则容易出现解码结果为空的情况!但补码方式crypto-js默认使用PKCS#7而在后端我们使用了PKCS#5。PKCS#7兼容PKCS#5,两者的区别可以参看此链接:

JAVA实现AES加密、解密 - 字节悦动 - 博客园 (cnblogs.com)

crypto-js安装:npm install crypto-js

先用decodeURIComponent函数处理URL中的参数部分,得到的字符串调用解密方法解密,加密解密可以放在新建的encryption.js文件中:

import CryptoJS from "crypto-js"; //引用AES源码js
var key = CryptoJS.enc.Utf8.parse("1234657812345678"); //十六位十六进制数作为秘钥
var iv = CryptoJS.enc.Utf8.parse("1234657812345678");//十六位十六进制数作为秘钥偏移量
//解密方法
export function Decrypt(decryptStr) {
  const decryptBase64Str = CryptoJS.enc.Base64.parse(decryptStr);
  const createCode = CryptoJS.lib.CipherParams.create({
    ciphertext: decryptBase64Str,
  });
  const decryptedData = CryptoJS.AES.decrypt(createCode, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  const decryptedStr = CryptoJS.enc.Utf8.stringify(decryptedData).toString();
  return decryptedStr;
}
//加密方法
export function Encrypt(word) {
    var srcs = CryptoJS.enc.Utf8.parse(word);
    var encrypted = CryptoJS.AES.encrypt(srcs, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
}

如果不希望用base64编码加密文件,还可以使用hex输出为16进制字符串:

byte[] encryptedBytes = cipher.doFinal(getBytes(text));

return javaEncodeURIComponent(Base64.getEncoder().encodeToString(encryptedBytes ));

改为:

return Hex.encodeHexString(cipher.doFinal(content.getBytes("UTF-8")));

但输出字符串较长,根据实际使用情况自省判断使用哪种方式。

前端使用Vue和CryptoJS的AES CBC(Cipher Block Chaining)加密,通常涉及以下几个步骤: 1. **加密** - 使用`CryptoJS.AES.encrypt()`函数,传入明文(待加密的数据)、密钥(Key,用于加密解密的同一条字符串)和IV(初始化向量,每次加密都要变化保持安全)。 - 示例代码: ```javascript const key = 'your_secret_key'; const iv = CryptoJS.lib.WordArray.random(16); // 16字节(128位) const plaintext = 'your_message'; // 明文 const ciphertext = CryptoJS.AES.cbcEncrypt(plaintext, key, { iv }); ``` 2. **Base64编码** - 为了跨平台传输,通常将密文和IV转换成Base64格式发送后端。 3. **后端解密** - 后端Java需要使用相应的库,比如Bouncy Castle或Java Cryptography Extension (JCE),解码Base64后的密文和IV。 - 解密代码示例: ```java import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import java.util.Base64; // 首先添加BouncyCastleProvider Security.addProvider(new BouncyCastleProvider()); byte[] base64Ciphertext = "..." // 前端传来的Base64编码的密文 String base64Iv = "..." // IV Base64编码 byte[] decodedCiphertext = Base64.getDecoder().decode(base64Ciphertext); byte[] decodedIv = Base64.getDecoder().decode(base64Iv); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec(decodedIv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC"); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] decryptedText = cipher.doFinal(decodedCiphertext); ``` 确保在两端使用的加密解密配置(如密钥长度、填充模式等)都是一致的。如果问题仍然存在,检查编码、传递过程中是否有丢失或乱序的情况,或者尝试排除其他潜在的网络问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值