keytool 能够创建并管理 keystore 中 key 的记录 (Key Entry), 每一条 key 的记录都包含一个私钥和与之关联的证书 “链” (Certificate Chain). “链” 中的第一张证书包含关联这个私钥的公钥.
当 keys 首次被创建的时候 (-genkeypair
), “链” 只有一个元素: 自签名证书. 发布者 (签发者) 与主题 (拥有被这个证书认证的公钥的实体) 相同的证书称作 “自签名证书”. -genkeypair
被用于生成公私钥对, 这个命令同时也会将公钥包装进自签名证书.
稍后, 一旦 CSR (Certificate Signing Request) 证书签名请求发送给发证机构 (-certreq
), 来自发证机构 (CA) 的响应就会被导入 (-importcert
), 然后自签名证书会被替换成一条 “证书链”. “链” 的底部是一个由认证了这个公钥的 CA 颁发的证书. 与之相邻的是认证 CA 的公钥的证书: 在很多场景, 这是一个自签名的证书 (一张来自 CA 的, 用于认证其自己的公钥的证书), 也是 “链” 中最后一个证书.
其他场景, CA 可能会返回一个证书链. “链” 底部的证书也是一张由 CA 签发, 认证了 key 的公钥的证书, 但是第二张证书却是一个由其他的 CA 签发的证书, 用于认证用户发送 CSR 请求的 CA 的公钥. 然后 “链” 中的再下一张证书, 用于认证这第二个 CA 的密钥, 以此类推直到自签名的根证书. 从第二张开始, 每一个张数链中的证书都用于认证前一张证书的公钥.
顶层 (根) 证书是自签名的, 然而, 对根证书的公钥的 “信任” 实际上却不是来自于根证书自身, 而是来自其他源: 根证书的公钥是公开的, 将它保存在证书中唯一原因是因为这种规范被很多工具支持, 所以在这个场景, 证书本身只是根证书公钥的载体. 在用户添加根证书到 keystore 之前, 应当先检查 (-printcert
) 它的 “指纹” 并与发证机构的官网的作比较确保一致.