CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Java 生态与工具链/课时/Java 加密基础
RawBlame
课时目录12 节

Java 生态与工具链

  1. 01Java 生态地图
  2. 02数据库访问
  3. 03Hibernate 深入
  4. 04EBean ORM
  5. 05日志框架
  6. 06Javadoc 与文档
  7. 07Play Framework
  8. 08Javalin 微框架
  9. 09REST Assured
  10. 10JMeter 性能测试
  11. 11Java 加密基础
  12. 12综合练习

Java 加密基础

cryptography;JCA/JCE 直觉。

30 分钟

Java 加密基础

日志里不能打密码,数据库里不应存明文。JCA/JCE(Java Cryptography Architecture / Extension)提供哈希、对称加密、非对称加密与签名 API——本课建立安全直觉,供 spring-boot-essentials 的 Spring Security 与 HTTPS 配置理解底层,并遵循 java-core-essentials 的「不可变、显式异常」风格。

学习目标

  • 用 MessageDigest 做 SHA-256 哈希,理解盐(salt)的作用
  • 用 Cipher 做 AES-GCM 加解密,选对模式与 IV
  • 区分「哈希存密码」与「加密可还原字段」的适用场景

密码哈希(不可逆)

import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;

public final class PasswordHasher {
    private static final SecureRandom RNG = new SecureRandom();

    public static String hash(char[] password) throws Exception {
        byte[] salt = new byte[16];
        RNG.nextBytes(salt);
        byte[] hash = sha256(concat(salt, new String(password).getBytes()));
        return Base64.getEncoder().encodeToString(salt)
            + "$" + Base64.getEncoder().encodeToString(hash);
    }

    private static byte[] sha256(byte[] input) throws Exception {
        return MessageDigest.getInstance("SHA-256").digest(input);
    }
}

生产环境请用 BCrypt / Argon2(Spring Security 的 PasswordEncoder),上述代码仅说明 JCA 用法。SHA-256 单次哈希对密码仍不够慢,易被彩虹表攻击。

AES-GCM 对称加密(可还原)

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public final class AesGcm {
    private static final int TAG_BITS = 128;

    public static byte[] encrypt(byte[] key, byte[] plain) throws Exception {
        byte[] iv = new byte[12];
        new SecureRandom().nextBytes(iv);
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"),
            new GCMParameterSpec(TAG_BITS, iv));
        byte[] cipherText = cipher.doFinal(plain);
        return concat(iv, cipherText); // 存储时 IV 与密文一起
    }
}

禁止 AES-ECB;GCM 同时提供机密性与完整性。密钥长度 128/256 位,从 KMS 或环境变量读取,不要硬编码进 Git。

场景选型

需求方案Java API / 库
存用户密码慢哈希 + 盐BCryptPasswordEncoder
加密数据库 PIIAES-GCM,密钥轮换Cipher + 密钥管理
HTTPS 证书TLSJVM truststore / Let's Encrypt
API 签名HMAC-SHA256Mac.getInstance("HmacSHA256")

常见错误

  • 自己发明加密协议或拼接 MD5
  • IV 固定或重用(GCM 灾难)
  • 把密钥写在 application.yml 并提交仓库
  • 用 Random 代替 SecureRandom

练习

  • 用 MessageDigest 对比同一字符串 SHA-256 两次结果一致
  • 实现 AES-GCM 加解密 round-trip 单元测试,篡改密文后解密应失败
  • 查 Spring Security 文档,说明 BCryptPasswordEncoder 比 SHA-256 更适合密码的原因

小结

哈希存密码、AES-GCM 加密字段、TLS 保护传输——JCA 是 Spring Security 的地板。 下一课综合 REST Assured 与 JMeter,测一个完整 Spring API。

加载本节练习…
← 上一课JMeter 性能测试下一课 →综合练习