前后端 AES 加解密

本贴最后更新于 594 天前,其中的信息可能已经事过景迁

前后端 AES 加解密

1.场景

目前在公司有一个业务需求,会员邀请新会员注册时。前端生成邀请码后进行 AES 加密,后端解密后将邀请码存储到数据库中,是前端加密,后端解密的场景。在 CSDN、掘金等平台尝试了几个例子,又自己修改了下后达成了想要的效果。写这篇文章用以记录存档,欢迎大家讨论交流!

2.类库使用

3.后端代码实现

工具类:

这个 ENCODE_KEY 的长度有指定要求,所以我用 Hutool 的 MD5 加密工具将字符串加密了一层。

IV_KEY 偏移量是 16 位,同样有固定长度要求。

本文更新:实际场景中如果使用 get 方式传递密文,有可能出现 + 号特殊字符被转义的情况。于是更新了写法。

import cn.hutool.core.codec.Base64; import cn.hutool.core.net.URLDecoder; import cn.hutool.core.net.URLEncodeUtil; import cn.hutool.core.util.CharsetUtil; import cn.hutool.crypto.Mode; import cn.hutool.crypto.Padding; import cn.hutool.crypto.digest.DigestUtil; import cn.hutool.crypto.symmetric.AES; public class KeyUtil { /** * 密钥key */ private static final String ENCODE_KEY = DigestUtil.md5Hex("xx"); /** * 偏移量。16 字节 */ private static final String IV_KEY = "4382822409223508"; /** * 将加密字符串进行解密 * * @param data 加密字符串 * @return 解密后的结果 */ public static String decryptFromString(String data) { //先进行URL解码,避免特殊符号带来的问题 data = URLDecoder.decode(data, CharsetUtil.CHARSET_UTF_8); AES aes = new AES(Mode.CBC, Padding.ISO10126Padding, Base64.decode(ENCODE_KEY), IV_KEY.getBytes()); return aes.decryptStr(Base64.decode(data)); } /** * 将字符串进行加密 * * @param data 未加密的字符串 * @return 加密后的密文结果 */ public static String encryptFromString(String data) { AES aes = new AES(Mode.CBC, Padding.ISO10126Padding, Base64.decode(ENCODE_KEY), IV_KEY.getBytes()); //将Base64加密后的结果,进行URL编码,避免GET方式传输的问题 return URLEncodeUtil.encode(Base64.encodeUrlSafe(aes.encrypt(data))); } }

Junit 测试类:

@Test public void testHutoolDecrypt() { String encryptData = KeyUtil.encryptFromString("Hello World"); System.out.println("加密:" + encryptData); String decryptData = KeyUtil.decryptFromString(encryptData); System.out.println("解密:" + decryptData); }

测试结果:

image

4.前端代码实现(只包含加密部分)

从上面的 GitHub 仓库地址下载了 js 代码后,将 js 本地引用,没有使用 npm 安装的方式使用(太麻烦....)

下方是例子:

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body></body> <script src="js/crypto-js.js"></script> <script> // 待加密的原文,使用 utf-8 编码处理 let message = CryptoJS.enc.Utf8.parse("加密原文"); // 密钥,我这里随意填写的,和后端的ENCODE_KEY对应即可 let key = CryptoJS.enc.Base64.parse("key"); // iv,和后端的IV_KEY对应即可 let iv = CryptoJS.enc.Utf8.parse("4382822409223508"); // 加密 let encrypted = CryptoJS.AES.encrypt(message, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Iso10126, }); // 密文,使用 base64 编码后使用URL函数再转一遍,避免GET方式调用的问题 let cipherTextBase64 = encodeURIComponent( CryptoJS.enc.Base64.stringify(encrypted.ciphertext) ); // 打印密文 console.log(cipherTextBase64); </script> </html>

前端加密后的结果在浏览器控制台上进行了打印,可以复制后直接调用 java 代码的解密 function 进行测试,我这里不再进行截图演示。

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3198 引用 • 8215 回帖
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    730 引用 • 1280 回帖 • 4 关注
  • 加密
    18 引用 • 60 回帖
2 操作
chirsgod 在 2023-09-08 16:41:55 更新了该帖
chirsgod 在 2023-09-08 16:40:39 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...