1. 概述
本文简要介绍 Java Keystore(密钥库)与 Truststore(信任库)之间的核心区别,以及它们在 SSL/TLS 安全通信中的作用。
2. 基本概念
在大多数需要 SSL/TLS 安全通信的场景中,我们都会用到 Keystore 和 Truststore。
这些通常是受密码保护的文件,和我们的应用程序运行在同一台服务器上。在 Java 8 及更早版本中,默认的 Keystore 格式是 JKS(Java KeyStore)。
从 Java 9 开始,默认格式变更为 PKCS12。JKS 是 Java 特有的格式,而 PKCS12 是一种标准化、跨语言的格式,用于安全地存储私钥和证书。
3. Java Keystore
✅ Java Keystore 主要用于存储私钥、包含公钥的证书,或者密钥,用于各种加密操作。
通常,Keystore 存储的是我们应用自己的密钥,比如用于签名或验证数据的密钥。我们可以通过别名(alias)来快速查找。
在服务端使用 HTTPS 时,Keystore 的作用尤为明显。SSL 握手过程中,服务端会从 Keystore 中取出私钥,并将对应的公钥和证书发送给客户端。
如果是双向认证(mutual authentication),客户端也需要提供自己的证书,这时客户端也会使用 Keystore。
⚠️ Java 没有默认的 Keystore,所以如果我们需要启用加密通信,必须设置以下 JVM 参数:
javax.net.ssl.keyStore
:指定 Keystore 文件路径javax.net.ssl.keyStorePassword
:指定 Keystore 密码javax.net.ssl.keyStoreType
:可选,指定 Keystore 类型(默认为 PKCS12)
此外,Keystore 中的密钥也可以用于其他用途:
- 私钥用于签名或解密
- 公钥用于验证或加密
- 对称密钥用于加解密数据
我们也可以通过 Java 代码来操作 Keystore,例如使用 KeyStore
类进行加载、读取和写入等操作。
4. Java Truststore
✅ Truststore 与 Keystore 相反,它存储的是我们信任的第三方证书,用于验证对方的身份。
举个例子:客户端通过 HTTPS 连接 Java 服务端时,服务端会从 Keystore 中取出证书发给客户端。客户端则会从自己的 Truststore 中查找该证书或其签发机构(CA),如果找不到,就会抛出 SSLHandshakeException
,连接失败。
Java 自带了一个默认的 Truststore,名为 cacerts
。在 Java 8 及之前版本中,它位于 $JAVA_HOME/jre/lib/security
,Java 9 及以后版本则位于 $JAVA_HOME/lib/security
。
这个文件中预置了多个权威 CA 的证书,例如:
$ keytool -list -keystore cacerts
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 92 entries
verisignclass2g2ca [jdk], 2018-06-13, trustedCertEntry,
Certificate fingerprint (SHA1): B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D
可以看到,这个 Truststore 包含 92 个信任的证书条目,其中包括 verisignclass2g2ca
。这意味着 JVM 默认信任由该 CA 签发的证书。
同样,我们可以通过 JVM 参数自定义 Truststore:
javax.net.ssl.trustStore
:指定 Truststore 文件路径javax.net.ssl.trustStorePassword
:Truststore 密码javax.net.ssl.trustStoreType
:Truststore 类型(默认为 JKS)
5. 总结
对比点 | Keystore | Truststore |
---|---|---|
✅ 用途 | 存储本地私钥和证书 | 存储信任的第三方证书 |
✅ 作用 | 证明自己 | 验证对方 |
⚠️ 默认 | 无 | 有(cacerts) |
🔐 密码 | 必须设置 | 可选设置 |
Keystore 和 Truststore 是 Java 安全通信的基石。理解它们的用途和区别,有助于我们在配置 HTTPS、双向认证等场景时避免踩坑。
如需深入了解 Java 的 SSL/TLS 实现,推荐阅读官方的 JSSE 参考指南 或 Baeldung 提供的 Java SSL 教程。