基于 AES + Base64 的密码加密工具类实现与优化
| 这个作业属于哪个课程 | 202501福大-软件工程实践-w班 |
| 这个作业要求在哪里 | 软件工程实践总结&个人技术博客 |
| 这个作业的目标 | 完成个人技术总结 |
| 其他参考文献 | 阿里巴巴Java开发手册、Git Flow工作流指南、敏捷开发实践 |
目录
- 基于 AES + Base64 的密码加密工具类实现与优化
- 1. 技术概述
- 2. 技术详述
- 2.1 背景与选型原因
- 2.2 核心实现逻辑
- 密钥生成机制(关键)
- 2.3 加密流程图
- 2.4 解密流程图
- 2.5 使用示例
- 3. 技术使用中遇到的问题与解决过程
- 问题 1:不同 JDK/OS 下密钥不一致,导致解密失败
- 现象:
- 根本原因:
- 解决方案:
- 问题 2:Base64 字符串含 / 和 +,在 URL 中被错误解析
- 现象:
- 解决方案:
- 4. 总结
- 5. 参考文献
基于 AES + Base64 的密码加密工具类实现与优化
1. 技术概述
本文聚焦于在 Java 后端开发中,如何通过 AES 对称加密 配合 Base64 编码 实现敏感数据(如设备指令、配置项)的安全存储与传输。该方案适用于需要可逆加解密的场景,尤其在无法使用 bcrypt 等单向哈希算法时作为替代方案。技术难点在于密钥生成的一致性、跨平台兼容性保障以及性能开销控制。
2. 技术详述
2.1 背景与选型原因
在“规巢”宿舍管理系统开发中,用户登录密码采用 bcrypt 安全哈希存储,但部分业务(如设备控制指令)需支持解密还原原始内容。由于 bcrypt 是单向函数,无法满足需求,我们设计了通用加密工具类 PasswdUtil,基于 AES-128 对称加密 + Base64 编码 实现可逆加密。
2.2 核心实现逻辑
PasswdUtil.java 提供两个核心方法:
encode(String data):明文 → AES 加密 → Base64 编码 → 密文字符串
decode(String encryptedData):Base64 解码 → AES 解密 → 明文字符串
密钥生成机制(关键)
private static SecretKeySpec generateKeyFromPassword() {
String password = "app@guicao"; // 固定密钥种子(生产环境应从配置读取)
byte[] keyBytes = new byte[16]; // AES-128 要求 16 字节密钥
byte[] pwdBytes = password.getBytes(StandardCharsets.UTF_8);
System.arraycopy(pwdBytes, 0, keyBytes, 0, Math.min(pwdBytes.length, 16));
return new SecretKeySpec(keyBytes, "AES");
}
直接从固定字符串派生 16 字节密钥,确保跨平台一致性。
避免使用 SecureRandom + KeyGenerator 组合,防止 JDK/OS 差异导致密钥不一致。
2.3 加密流程图

2.4 解密流程图

2.5 使用示例
// 加密
String plain = "device_cmd_123";
String encrypted = PasswdUtil.encode(plain);
System.out.println("Encrypted: " + encrypted); // e.g., U2FsdGVkX1...
// 解密
String decrypted = PasswdUtil.decode(encrypted);
System.out.println("Decrypted: " + decrypted); // 输出: device_cmd_123
3. 技术使用中遇到的问题与解决过程
问题 1:不同 JDK/OS 下密钥不一致,导致解密失败
现象:
本地 Windows + JDK 17 加密成功,但 Linux + JDK 11 服务器解密时报错:
javax.crypto.BadPaddingException: Given final block not properly padded
根本原因:
早期版本使用 SecureRandom.getInstance("SHA1PRNG") 生成密钥,但该算法在不同平台底层实现不同,即使种子相同,输出也可能不一致。
解决方案:
弃用 KeyGenerator,直接从固定字符串构造密钥(见 2.2 节代码)。
问题 2:Base64 字符串含 / 和 +,在 URL 中被错误解析
现象:
将加密结果作为 URL 参数传递(如 ?token=abc+/123==),后端收到时 + 变为空格,/ 被截断。
解决方案:
使用 URL 安全的 Base64 编码器:
// encode 方法中
return Base64.getUrlEncoder().withoutPadding().encodeToString(cipherText);
// decode 方法中
byte[] decoded = Base64.getUrlDecoder().decode(encryptedData);
getUrlEncoder() 将 + 替换为 -,/ 替换为 _
withoutPadding() 移除末尾 =,避免 URL 编码问题
4. 总结
PasswdUtil 提供了一套轻量、可靠、可逆的加密方案,适用于设备指令、API 密钥等需加解密的场景。
绝对不可用于用户密码存储——密码必须使用 bcrypt/scrypt/PBKDF2 等慢哈希算法。
密钥管理是安全核心:生产环境务必通过配置中心或环境变量注入,禁止硬编码。
跨平台部署前必须验证加解密一致性,推荐直接派生密钥而非依赖随机数生成器。
若用于网络传输(尤其是 URL),必须使用 URL 安全 Base64。
5. 参考文献
Java Cryptography Architecture (JCA) Reference Guide
Oracle官方文档
https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.htmlBase64 Encoding in Java: Standard vs URL-Safe
Baeldung
https://www.baeldung.com/java-base64-url-safe
相关推荐
AES256加密工具类,及其所必须的jar包
该资源是AES加密工具类; 包括源码:AES256Util.java 及其必要jar包:bcprov-jdk16-141.jar 和 javabase64-1.3.1.jar
C++实现数据加密解密工具:从凯撒密码到AES-256的完整实践
数据加密是信息安全领域的核心技术,通过特定算法将明文转换为密文,确保数据在存储和传输过程中的机密性。其原理基于密码学理论,利用密钥对数据进行变换,使得只有授权方能够恢复原始信息。这项技术的核心价值在于保护敏感数据免受未授权访问,广泛应用于文件保护、通信安全、身份验证等场景。本文聚焦于C++编程实践,通过构建一个命令行加密解密工具,深入解析凯撒密码、异或加密和AES-256等算法的实现细节。文章特别探讨了AES-256这一现代对称加密标准在C++中的实现方法,并详细说明了如何避免异或加密中常见的空字符陷阱。通
AES+BASE64加密算法
对字符串进行aes+base64的混合加密传输。
Delphi7AES加密解密与JAVA互转(默认128位+ECB+PKCS5Padding+先BASE64再HEX)
Delphi7可与JAVA互转的AES加密解密算法(默认128位+ECB+PKCS5Padding+先BASE64再HEX),保证纯源码(ElAES基础上并参考大牛代码),不带任何控件。
AES加密base64编码
AES加密,使用base64编码,可以兼容ios


