作者简介:大家好,我是CodeStats。一个在底层技术上“考古”了四年的硬核爱好者,也是WWAIC(全周项目AI编程)范式的提出者和实践者。我曾手写过一个完整的Java Web框架(从IoC容器到嵌入式Tomcat,代码全开源),也喜欢用通俗的语言拆解CPU、JVM、操作系统的运行本质。
我的技术信条:所有高深的技术,最后都能用大白话讲清楚。如果讲不清楚,说明还没真正理解。
📖 本文获取(你将学到什么?)
读完这篇文章,你将彻底搞懂以下5个核心问题,从此Java加解密面试对你不再设防:
| 序号 | 你将掌握的知识点 | 解决的核心困惑 |
|---|---|---|
| ① | Java加解密算法的三大分类 | 对称加密、非对称加密、哈希算法到底是什么? |
| ② | 对称加密 vs 非对称加密的使用场景、密钥长度和密文长度 | 什么时候用AES?什么时候用RSA? |
| ③ | 哈希算法有哪些?如何利用MD5进行登录验证?加盐怎么用? | 密码为什么不能明文存储? |
| ④ | 国密算法SM2/SM3/SM4分别是什么类型?对应哪些国际算法? | 国密算法如何对标国际标准? |
| ⑤ | SM4有哪些工作模式?CBC/CTR/GCM区别是什么?Base64和Hex长度有何区别?为什么需要IV向量? | SM4怎么选模式?IV是什么? |
一、Java加解密算法如何分类?
Java中的加解密算法通常可以分为三大类:
1.1 对称加密(Symmetric Encryption)
定义:加密和解密使用同一个密钥的加密算法。
特点:
✅ 加密速度快、效率高,适合大量数据加密
❌ 密钥分发和管理困难——如何安全地把密钥告诉对方?
常见算法:AES、DES、3DES、SM4
1.2 非对称加密(Asymmetric Encryption)
定义:加密和解密使用一对密钥:公钥(Public Key)和私钥(Private Key)。公钥加密的数据,只能用对应的私钥解密。
特点:
✅ 安全性高,解决了密钥分发问题
❌ 速度较慢,不适合加密大量数据
常见算法:RSA、ECC(椭圆曲线加密)、DSA、SM2
1.3 哈希算法(Hash Algorithm / Message Digest)
定义:将任意长度的数据转换成固定长度的、不可逆的哈希值(散列值)。
特点:
🔒单向、不可逆:无法从哈希值还原出原始数据
✅ 主要用于验证数据完整性,而非加密
常见算法:MD5、SHA-1、SHA-256、SM3
二、对称加密和非对称加密:使用场景、密钥长度与密文长度
2.1 使用场景对比
| 对比维度 | 对称加密 | 非对称加密 |
|---|---|---|
| 密钥数量 | 1个(加解密共用) | 2个(公钥加密,私钥解密) |
| 加密速度 | ✅ 快 | ❌ 慢 |
| 密钥分发 | ❌ 困难 | ✅ 安全(公钥可公开) |
| 典型场景 | 大量数据加密、数据库字段加密 | 密钥分发、数字签名、身份认证 |
| 代表算法 | AES、SM4 | RSA、SM2 |
💡工程实践中的黄金组合:用非对称加密(如RSA/SM2)安全地传输对称加密(如AES/SM4)的密钥,然后用对称加密来加密实际的大量数据。这就是混合加密的经典模式。
2.2 密钥长度
| 算法 | 密钥长度(位) | 密钥长度(字节) |
|---|---|---|
| AES | 128 / 192 / 256 | 16 / 24 / 32 字节 |
| SM4 | 128(固定) | 16 字节 |
| RSA | 2048 / 3072 / 4096 | 256 / 384 / 512 字节 |
| SM2 | 256(固定) | 32 字节 |
⚠️注意:1字节 = 8位。所以“128位”就是“16字节”。代码中常遇到
InvalidKeyException,多半是密钥字节数不对。
2.3 密文长度
| 算法 | 密文长度 | 说明 |
|---|---|---|
| AES/SM4(对称) | 与明文等长(填充后) | 分组加密,需按块大小(16字节)填充 |
| RSA(非对称) | 与密钥长度相同 | 如2048位密钥 → 密文256字节 |
| SM2(非对称) | 64 + 明文长度 + 32 字节 | C1固定64字节 + C2(明文) + C3固定32字节 |
为什么RSA不能加密大数据?
RSA加密的明文必须比密钥长度少11字节(PKCS#1填充)。例如2048位(256字节)的RSA密钥,最多只能加密245字节的明文。所以RSA通常只用来加密对称密钥或小数据。
三、哈希算法有哪些?如何利用MD5进行登录验证?
3.1 常见哈希算法
| 算法 | 输出长度(位) | 输出长度(字节) | 安全性 |
|---|---|---|---|
| MD5 | 128 | 16 | ❌ 已破解,不推荐用于安全场景 |
| SHA-1 | 160 | 20 | ❌ 已破解 |
| SHA-256 | 256 | 32 | ✅ 安全 |
| SM3 | 256 | 32 | ✅ 安全 |
3.2 为什么密码不能明文存储?
如果数据库被攻破,所有用户的明文密码将直接暴露。正确的做法是:存储密码的哈希值,而非明文。
3.3 MD5登录验证流程(⚠️ 注意:MD5已不安全,仅作原理演示)
注册时:
text
用户密码 "123456" → MD5加密 → "e10adc3949ba59abbe56e057f20f883e" → 存入数据库
登录时:
text
用户输入 "123456" → MD5加密 → "e10adc3949ba59abbe56e057f20f883e" → 与数据库比对 → ✅ 一致则登录成功
3.4 加盐(Salting)场景示例
为什么需要加盐?
不加盐的话,相同密码会产生相同的MD5值。黑客可以用彩虹表(预先计算的MD5字典)快速破解。
加盐后的流程:
注册时:
text
1. 为用户生成随机盐值(如 "xYz9Kj3M") 2. 计算:MD5(密码 + 盐值) = "a8f5d6e7c8b9a1..." 3. 存储:{MD5值, 盐值} 到数据库登录时:
text
1. 根据用户名取出 {存储的MD5, 盐值} 2. 计算:MD5(用户输入密码 + 盐值) 3. 比对是否一致加盐的效果:即使两个用户的密码都是"123456",由于盐值不同,最终存储的哈希值也完全不同,彩虹表彻底失效。
⚠️ 生产环境强烈建议
MD5已经过时。对于新项目,强烈推荐使用 BCrypt、SCrypt 或 Argon2,它们内置加盐且被设计为“慢哈希”,能有效抵抗暴力破解。
四、国密算法SM2/SM3/SM4分别是什么?对应什么国际算法?
国密算法是国家密码管理局认定和发布的一系列具有自主知识产权的国产密码算法标准。
| 国密算法 | 算法类型 | 对标国际算法 | 主要用途 |
|---|---|---|---|
| SM2 | 非对称加密(椭圆曲线) | RSA / ECDSA / ECDH | 数字签名、密钥交换、公钥加密 |
| SM3 | 哈希算法(杂凑算法) | SHA-256 | 数据完整性校验、消息认证 |
| SM4 | 对称加密(分组密码) | AES | 大量数据加密 |
4.1 SM2(非对称加密)
SM2基于椭圆曲线密码(ECC),用256位密钥就能达到RSA 2048/3072位的同等安全强度。主要包含数字签名、密钥交换和公钥加密三大功能。
4.2 SM3(哈希算法)
SM3是密码杂凑算法,输出256位(32字节)的哈希值,用于替代MD5/SHA-1/SHA-256等国际算法。
4.3 SM4(对称加密)
SM4是分组对称密码算法,分组长度和密钥长度均为128位(16字节)。它承担了生产环境中最繁重的数据加解密任务。
🌟国密TLS的经典组合:SM2证书 + SM4加密 + SM3哈希,构成完整的国产加密通信套件。
五、SM4的工作模式:CBC/CTR/GCM区别、Base64 vs Hex、为什么需要IV?
5.1 SM4有哪些工作模式?
SM4作为分组密码(块大小128位/16字节),需要工作模式来处理任意长度的数据。常见模式包括:ECB、CBC、CFB、OFB、CTR、GCM、CCM、XTS。
5.2 CBC vs CTR vs GCM 核心对比
| 对比维度 | CBC | CTR | GCM |
|---|---|---|---|
| 是否需要填充 | ✅ 需要(PKCS7Padding) | ❌ 不需要 | ❌ 不需要 |
| 加密可并行 | ❌ 不可并行 | ✅ 完全可并行 | ✅ 完全可并行 |
| 解密可并行 | ✅ 可并行 | ✅ 完全可并行 | ✅ 完全可并行 |
| 完整性校验 | ❌ 无 | ❌ 无 | ✅ 自带认证标签(AEAD) |
| 推荐度 | ⚠️ 可用(兼容性好) | ✅ 推荐(高性能) | ⭐强烈推荐 |
CBC模式:每个明文块先与前一个密文块异或,再加密。加密必须串行,但解密可以并行。
CTR模式:通过加密计数器生成密钥流,再与明文异或。加解密完全可并行,性能极高。
GCM模式:在CTR基础上增加了消息认证功能,同时提供加密和完整性校验(AEAD模式)。这是目前最安全、最现代的选择。
5.3 为什么需要IV向量?
IV(初始化向量)的作用是确保相同明文在不同次加密中产生不同的密文。
CBC模式:IV必须随机且不可预测,长度固定为16字节
CTR/GCM模式:IV(常称Nonce)必须唯一,GCM推荐12字节
⚠️致命陷阱:CTR和GCM模式下,同一密钥的Nonce绝对不允许重复使用,否则密钥流会重复,攻击者可通过异或直接破解明文。
5.4 Base64编码 vs Hex编码:长度有何区别?
加密后的密文是二进制字节数组,需要编码成文本才能传输或存储。两种常见编码方式:
| 编码方式 | 说明 | 16字节密文的长度 |
|---|---|---|
| Hex(十六进制) | 1字节 → 2个十六进制字符 | 16 × 2 =32字符 |
| Base64 | 每3字节 → 4个字符 | ⌈16/3⌉ × 4 =24字符 |
为什么长度不同?
Hex:简单直接,每个字节拆成两个字符,长度固定为
密文长度 × 2Base64:用64个可打印字符表示二进制,压缩效率更高,长度约为
密文长度 × 4/3
选哪个?
Hex:可读性好,适合调试、日志
Base64:更紧凑,适合网络传输
📝 总结
| 算法分类 | 核心特点 | 代表算法 | 典型场景 |
|---|---|---|---|
| 对称加密 | 一个密钥,加解密快 | AES、SM4 | 大量数据加密 |
| 非对称加密 | 公钥/私钥对,慢但安全 | RSA、SM2 | 密钥分发、数字签名 |
| 哈希算法 | 不可逆,固定长度 | SHA-256、SM3 | 密码存储、完整性校验 |
💡Java中的加密框架:Java通过JCA(Java Cryptography Architecture)和JCE(Java Cryptography Extension)提供加密功能的框架和API。核心类是
javax.crypto.Cipher,它整合了算法/工作模式/填充模式。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注👀,后续会持续输出更多Java技术干货!
有疑问欢迎在评论区留言交流~