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

双向 TLS:客户端证书如何参与身份认证

真实验证双向 TLS:need/want/none 与客户端证书的各种组合,TLS 1.3 下没有证书时 startHandshake 先返回、第一次读写才失败;不被信任的客户端证书根本不会被发送;客户端有多个身份时按服务器给出的 CA 列表选;并用 nginx 的 ssl_verify_client on/optional、curl、openssl 对照。

Java 双向TLS mTLS 客户端证书 JSSE nginx 真实验证 动画演示
Java 内部原理 2026-10-03

SocketChannel 半关闭:只结束发送不结束接收

真实验证 TCP 半关闭:shutdownOutput 之后仍可读而再写抛异常;用 lsof 看到 FIN_WAIT_2 与 CLOSE_WAIT;直接 close 会丢响应(Broken pipe);SocketChannel 里对端半关闭表现为 OP_READ 就绪且读到 -1,不处理会空转;SO_LINGER 0 的 close 发 RST,对端第 2 次读 Connection reset。

Java Socket 半关闭 shutdownOutput TCP 真实验证 动画演示
Java 内部原理 2026-10-03

网络超时分类:连接、读取和整体截止时间

真实验证 Java 网络超时的几种含义:连接超时(没有回应)与端口无人监听的立刻拒绝;SO_TIMEOUT 管的是每次 read,滴水的服务器 4 s 都不会触发 500 ms 的读超时;HttpRequest.timeout 只管到响应头;整体截止时间要用 orTimeout 或自己维护;Future.get 超时不取消任务。

Java 网络超时 Socket HttpClient SO_TIMEOUT 真实验证 动画演示
Java 内部原理 2026-10-03

Java 串口通信:把设备字节流变成可靠协议

用 jSerialComm 在伪终端(pty)上演示串口协议的常见问题:一个 45 字节的帧被分成 12, 12, 12, 9 几次读到;带 CRC 与重同步的解析器丢掉 21 字节噪声;三种读超时模式的差别;请求超时重试时用序号丢弃迟到的旧响应。没有接真实的串口硬件。

Java 串口 jSerialComm 协议设计 CRC 真实验证 动画演示
Java 内部原理 2026-10-03

PKIX 证书路径验证:Java 如何判断证书链可信

用 keytool 建一棵真实的证书树并用 CertPathValidator 验证:缺中间证书、顺序、信任锚;有效期必须覆盖整条链;pathlen、keyUsage、basicConstraints 违规各自的失败原因(getReason 与链下标);撤销检查默认开启、没有撤销信息时 SOFT_FAIL 也不放行。

Java PKIX 证书路径验证 CertPathValidator X.509 真实验证 动画演示
Java 内部原理 2026-10-03

AEAD 与 GCM:加密时为什么绝不能复用 nonce

用 JDK 的 AES-GCM 验证 nonce 重用的危害:任何输入被改都抛 AEADBadTagException;同一个 Cipher 对象会拦住 IV 重用但不同对象拦不住;同一密钥与 IV 加密两条消息密文 XOR 等于明文 XOR;随机 32 位 nonce 发 65536 条的碰撞率 39.3% 与生日公式吻合;GCM 解密不会提前释放明文。

Java AES-GCM AEAD nonce 密码学 真实验证 动画演示
Java 内部原理 2026-10-03

KeyAgreement:两端如何协商出共享密钥

用 KeyAgreement 验证:X25519 / P-256 / P-384 的密钥与共享秘密大小;X25519 120 μs 对 P-256 590 μs;不在曲线上与小阶点的公钥被拒绝;用自己实现并通过 RFC 5869 向量的 HKDF 派生密钥;无认证 DH 被中间人替换公钥,加签名后能发现。

Java 密钥协商 ECDH X25519 HKDF 真实验证 动画演示
Java 内部原理 2026-10-03

HMAC 与数字签名:共享密钥和私钥的边界

用 JDK 真实运行 HMAC 与数字签名:验证方持有 HMAC 密钥就能伪造任意消息;Ed25519、ECDSA、RSA 的签名大小与确定性;验证失败是 false 还是 SignatureException;HMAC 1.8 μs、Ed25519 验证 420.7 μs、RSA-2048 验证 34.1 μs。

Java HMAC 数字签名 Ed25519 ECDSA RSA 真实验证 动画演示
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 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号