知其然,知其所以然
Java 内部原理 2026-10-03

常量时间比较:为什么密钥标签不能直接 equals

量出不同比较方式的耗时与第一处不同位置的关系:4096 字节上手写循环 14.7 → 827.8 ns,Arrays.equals 22.5 → 76.0 ns,MessageDigest.isEqual 恒为约 1986 ns;String.equals 同样早退出;32 字节的测量不可靠;HMAC 标签应该用 MessageDigest.isEqual 比较。

Java 常量时间比较 MessageDigest.isEqual 时序攻击 真实验证 动画演示
Java 内部原理 2026-10-03

PBKDF2:密码存储为什么要慢一点

用 JDK 的 PBKDF2 验证:RFC 6070 标准向量一致;盐与迭代次数的作用;SHA256 60 万次迭代约 75.7 ms、耗时与迭代次数成正比;要 512 位输出耗时 2.0 倍;口令的 Unicode 规范化差异;登录验证流程与迭代次数的选择。

Java PBKDF2 口令哈希 盐 迭代次数 真实验证 动画演示
Java 内部原理 2026-10-03

证书固定 Pinning:额外信任约束如何维护

用自己的 CA 与 TLS 服务验证证书固定:pin 是公钥的 SHA-256(与 openssl、curl 交叉验证);换新密钥会失败而同密钥续期不会;备用 pin 让轮换平滑;只 pin 不验证会放过过期证书与错误主机名。

Java 证书固定 Pinning X509TrustManager TLS 真实验证 动画演示
Java 内部原理 2026-10-03

XML Digital Signature:签名验证不只是比一个摘要

真实运行 javax.xml.crypto.dsig:篡改被签名内容与签名值的检测;规范化让属性顺序、引号不影响签名而空白文本节点会;用文档自带的 KeyValue 验证会放过攻击者自己签的文档;签名包装让验证通过而应用处理了没被签名的元素;secureValidation 拒绝 SHA-1 与 512 位 RSA。

Java XML签名 XMLDSig 签名包装 C14N 真实验证 动画演示
Java 内部原理 2026-10-03

密钥轮换:Java 服务如何平滑切换加密材料

在 Java 里实际做密钥轮换:密文头部带 key id、新旧密钥并存、惰性重加密;信封加密轮换主密钥只重新包裹 DEK(71 ms 对 215 ms);两个字段分别读取会在轮换中读到不一致的 id 与密钥(失败 4.04%),不可变快照为 0;由 nonce 预算决定的轮换周期。

Java 密钥轮换 信封加密 AES-GCM 并发 真实验证 动画演示
Java 内部原理 2026-10-03

Java Security Parameters:算法限制如何影响兼容性

逐个打印 JDK 17、21、27 的默认安全参数并真实验证效果:TLSv1/1.1 与 TLS_RSA_* 默认握手失败、用 -Djava.security.properties 覆盖后成功;证书路径里 512 位 RSA 被拒绝、SHA1 的限制只对 JDK CA 锚定的链生效、收紧后 SHA1 与 1024 位失败。

Java 安全参数 java.security TLS jdk.tls.disabledAlgorithms 真实验证 动画演示
Java 内部原理 2026-10-03

jlink:裁剪出应用需要的 Java 运行时

用 jdeps 找出 java.base,java.logging,java.net.http,再用 jlink 裁剪运行时:从 350 MB 的完整 JDK 到 30.0 MB(strip-debug + zip-9);默认没有 CDS 归档导致 Hello 启动 40 ms 对 24 ms,加 --generate-cds-archive 追平;jdeps 看不到的反射依赖在镜像里 ClassNotFoundException;--bind-services 让镜像变成 163.1 MB。

Java jlink jdeps 运行时镜像 模块 真实验证 动画演示
Java 内部原理 2026-10-03

jpackage:把 Java 应用做成系统安装包

用 jpackage 在 macOS 上真实打包:app-image 的目录结构与 Demo.cfg 配置;默认带 63 个模块 155 MB,指定 --add-modules java.base 与 jlink 选项后 30 MB;修改 cfg 立即生效;ad-hoc 签名;dmg 58 MB、pkg 52 MB;--main-class 写错要到运行时才发现。

Java jpackage macOS 应用打包 jlink 真实验证 动画演示
Java 内部原理 2026-10-03

jdeps:从字节码分析模块和 API 依赖

用 jdeps 分析 netty-common、guava、commons-lang3 三个真实的库:各自需要的 JDK 模块;--jdk-internals 列出 sun.misc.Unsafe 的使用(netty 36 行、guava 22 行);多版本 jar 必须加 --multi-release;依赖图、缺失依赖;--generate-module-info;字符串反射的依赖 jdeps 看不到。

Java jdeps 模块依赖 jdk-internals 多版本JAR 真实验证 动画演示
Java 内部原理 2026-10-03

javap:从类文件反推 Java 编译结果

用 javap 逐项看 javac 21 的编译结果:类头与常量池(252 项)、-g 与 -parameters 的调试信息;字符串/枚举/模式 switch 与 record toString 的脱糖;字符串拼接 invokedynamic(4 条指令)对 StringBuilder(13 条);lambda、assert、finally 复制与 synchronized 的字节码。

Java javap 字节码 脱糖 javac 真实验证 动画演示
Java 内部原理 2026-10-03

JShell:用交互式会话验证 Java 想法

真实运行 jshell 与 JShell API:$N 临时变量、前向引用与重新定义、错误后继续;/vars /methods /list /drop /reset;启动 1038 ms、--class-path 加载 guava;API 里 snippet 的状态、EvalException,js.stop() 在 509 ms 后中断 while (true)。

Java JShell REPL jdk.jshell 交互式 真实验证 动画演示
Java 内部原理 2026-10-03

可复现 JAR:相同源码如何得到相同产物

实测同一份源码怎样得到逐字节相同的 JAR:javac 同一 JDK 下是确定的、跨 JDK 版本常量池排列会不同;jar 工具要加 --date 并保持条目顺序;Maven 要设置 project.build.outputTimestamp;换 JDK 会让 manifest 的 Created-By 或 Build-Jdk-Spec 与 Main.class 不同。

Java 可复现构建 JAR Maven outputTimestamp 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号