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

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

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

学习

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

更多

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

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
网络安全入门/课时/密码学与 PKI
RawBlame
课时目录12 节

网络安全入门

  1. 01安全职业与 IT 基础
  2. 02网络与安全基础
  3. 03操作系统加固
  4. 04密码学与 PKI
  5. 05身份与访问控制
  6. 06威胁与攻击向量
  7. 07防御技术与工具
  8. 08事件响应与取证
  9. 09云与虚拟化安全
  10. 10渗透测试入门
  11. 11合规与认证
  12. 12综合练习

密码学与 PKI

哈希、加盐、证书、TLS、Kerberos。

35 分钟

加密与 TLS:从哈希到证书链

这一课你将能做到

  1. 区分对称加密、非对称加密、哈希的适用场景,说清楚口令为什么要用 BCrypt
  2. 用 openssl 生成密钥与证书、验证一条真实站点的证书链
  3. 给 Spring Boot 配上 HTTPS,并按检查项评估自己平台的 TLS 配置

为什么要学

TLS 是现代互联网的信任基石,但你每天配的 server.ssl.* 背后发生了什么?面试里「HTTPS 为什么安全」几乎必问;实战里证书链配错、密码套件太弱、口令存明文,都是高频事故。不懂加密,你看不出 JWT 弱密钥的危害,也看不出为什么 MD5 存密码等于裸奔。

人话:哈希是「榨汁机」(不可还原),对称加密是「保险箱+同一把钥匙」,非对称加密是「信箱」(公开地址投递、私钥才能取)。

先建立图像

TLS 握手中的角色分工:

客户端                                服务器
  │ ── ClientHello(支持的套件+随机数) ──▶│
  │◀─ ServerHello + 证书链 ─────────────│ ①证书链验证:根CA→中间CA→站点证书
  │ ◀─ 用证书里的公钥协商会话密钥 ────────│ ②非对称加密只用于握手
  │ ════ 之后全部用会话密钥对称加密 ═════▶│ ③业务数据走对称加密(快)

三类工具各司其职:

工具可逆?用途例子
哈希(SHA-256)不可逆完整性校验、口令存储文件校验、BCrypt 存密码
对称(AES)可逆,同钥大量数据加密TLS 会话数据、磁盘加密
非对称(RSA/Ed25519)可逆,公私钥对密钥交换、签名TLS 握手、JWT 签名

跟着做

步骤 1:生成密钥对与自签证书

# 生成 EC 私钥 + 自签证书(有效期 365 天,仅测试用)
openssl ecparam -genkey -name prime256v1 -out server.key
openssl req -new -x509 -key server.key -out server.crt \
  -days 365 -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

步骤 2:本地验证证书在服务端可用

# 用 openssl 起一个 TLS 服务(自建环境演示)
openssl s_server -port 8443 -key server.key -cert server.crt -www &
# 客户端连接(-CAfile 指向自签证书,自签链需要手动信任)
openssl s_client -connect localhost:8443 -CAfile server.crt
# 观察输出:Verify return code: 0 (ok)

步骤 3:验证真实站点证书链

openssl s_client -connect httpbin.org:443 -showcerts
# 看 Certificate chain 段:0 站点证书 → 1 中间CA → (根CA预置在系统)
# Verify return code: 0 (ok) 表示链完整可信
# 不加 -CAfile 的自签站点会报 self signed certificate

步骤 4:检查 TLS 配置强弱

# 安装 testssl.sh 检查自建靶机的 TLS
git clone --depth 1 https://github.com/drwetter/testssl.sh.git
./testssl.sh/testssl.sh https://localhost
# 关注:协议版本(TLS1.0/1.1 应禁用)、弱套件、证书链完整性

步骤 5:口令存储实验(哈希必须加盐慢哈希)

# MD5/SHA 之所以不适合存口令:太快,GPU 每秒可算百亿次
echo -n "password123" | md5sum        # 瞬间完成
# Java 里正确做法(Spring Security 已内置):
// Spring Security 的口令编码器:BCrypt 自带盐、故意慢
PasswordEncoder encoder = new BCryptPasswordEncoder(12);
String hash = encoder.encode("password123");
boolean ok = encoder.matches("password123", hash);

步骤 6:Spring Boot 配 HTTPS

# 把自签证书转成 PKCS12 给 Spring Boot 用
openssl pkcs12 -export -in server.crt -inkey server.key \
  -out server.p12 -name server
# application.yml
server:
  ssl:
    key-store: classpath:server.p12
    key-store-password: ${SSL_KEYSTORE_PWD}   # 从环境变量注入
    key-store-type: PKCS12
  port: 8443

讲清楚要点

  1. 哈希不是加密:哈希不可逆,用于验证「内容相同」;加密可逆,用于保护「内容保密」。把「加密密码」说成哈希校验是面试常见错误。
  2. 口令存储三要素:加盐(防彩虹表)、慢函数(防暴力枚举)、可调成本因子(硬件进步时能升级)。BCrypt/Argon2/scrypt 都满足,MD5/SHA1/SHA256 直接存都不满足。
  3. 证书链验证逻辑:站点证书由中间 CA 签发,中间 CA 由根 CA 签发,根 CA 预置在操作系统信任库。缺中间证书是最常见部署事故——浏览器有的能补、curl 直接报错。
  4. 非对称加密不做业务加密:RSA 慢且有长度限制,TLS 只用它在握手阶段交换会话密钥,之后全走 AES 这类对称加密。
  5. 签名与加密是两件事:签名证明「谁发的、没被改」(用私钥签、公钥验);加密保证「只有收件人能读」。JWT 签名不加密——payload 默认 base64 可读。

你可能会懵的地方

  • HTTPS 抓包就完全看不到了吗? 不配密钥确实只能看到元数据。所以中间人攻击的核心是伪造证书:除非攻击者能把根证书装进你的信任库,否则链验证会失败。这就是公共 Wi-Fi 上仍建议全程 HTTPS 的原因。

  • 自签证书安全吗? 加密强度没问题,问题是「身份不可信」——任何人都能给自己签一张 localhost。公网服务必须用受信 CA 签发的证书,Let's Encrypt 免费解决这件事。

  • 为什么 BCrypt 的盐不用保密? 盐的作用是让相同口令产生不同哈希、让彩虹表失效,它随哈希一起存储,本身不需要保密。需要保密的是口令本身。

  • TLS 1.3 比 1.2 好在哪? 握手往返更少(1-RTT)、废除了 RSA 密钥传输改为前向安全的密钥交换(ECDHE)、砍掉全部弱套件。新部署应优先 1.3,至少保留 1.2 并禁用 1.0/1.1。

  • JWT 用 HS256 还是 RS256? HS256 共享密钥,适合单体应用;RS256/EdDSA 私钥签名、公钥验签,适合多服务:验证方拿不到私钥,被攻破一个服务也伪造不了 token。本站平台多模块场景建议非对称。

错法对照

错法问题正解
密码用 MD5/SHA256 直接存速度太快,撞库秒破BCrypt/Argon2 慢哈希 + 盐
自签证书上生产公网站点用户全屏告警,无法防钓鱼Let's Encrypt 等受信 CA
密钥硬编码在代码/配置里提交仓库即泄露环境变量 / KMS / Vault
只配证书不验证证书链部分客户端握手失败openssl s_client 验证 Verify code=0
用 RSA 直接加密大文件长度限制且极慢AES 加数据 + RSA 保护会话密钥

卡点急救

  1. 浏览器提示证书不受信任(自签):测试环境把自签 CA 导入系统信任库;生产直接换 Let's Encrypt(certbot 一条命令签发续期)。
  2. curl 报 unable to get local issuer certificate:服务端漏了中间证书。用 openssl s_client -showcerts 看链是否完整,把中间证书拼进 fullchain。
  3. Java 启动报 Invalid keystore format:JDK 版本与 PKCS12 参数不匹配,重新 openssl pkcs12 -export -legacy 或指定 -keypbe 兼容算法;确认 key-store-type 与文件一致。

面试常问

  • HTTPS 握手过程?为什么非对称加密只用在握手? ClientHello(套件+随机数)→ 服务器返回证书链 → 客户端验证链并用公钥协商会话密钥(TLS1.3 走 ECDHE 前向安全)→ 之后用会话密钥对称加密。非对称慢且 RSA 加密无前向安全,只适合短时的密钥协商;对称快,适合业务数据。

  • 为什么密码要 BCrypt 而不是 SHA256 加盐? SHA256 计算速度对 GPU 极快,即使加盐也能高速离线爆破;BCrypt/Argon2 故意慢、支持成本因子,且 BCrypt 内置盐管理。升级成本因子还能对抗硬件进步。

  • 证书链是怎么验证的?中间证书缺失会怎样? 从站点证书逐级向上找签发者,最终锚定到系统信任库里的根 CA,同时校验有效期、域名 SAN、吊销状态。缺中间证书时部分浏览器能 AIA 补链,curl/Java 默认直接握手失败。

自测三问

  1. 对称加密、非对称加密、哈希在 TLS 里各用在哪一步?
  2. 为什么说「MD5 存密码加盐」也不够?
  3. Spring Boot 配置 HTTPS 需要哪几项?私钥口令应该放哪?

小结一句话

哈希保完整、对称保效率、非对称保信任:TLS 用证书链建立身份,用握手换来会话密钥,而你的口令必须交给慢哈希保管。

延伸

  • Mozilla TLS 配置生成器
  • RFC 8446: TLS 1.3
  • 下一课:认证与授权——JWT、OAuth2 与 SSO 的原理与攻防。
加载本节练习…
← 上一课操作系统加固下一课 →身份与访问控制