keytool 是如何工作的:privateKeyEntry 和 trustedCertEntry?

How does keytool work: privateKeyEntry and trustedCertEntry?

好的,我先说说我所知道的 SSL 工作原理。

最重要的是我需要了解客户端证书的工作原理,因为我在设置 mTls istio 网关时遇到了问题。

所以,首先我需要密钥对,私有的和public。如果我理解正确,接下来我将使用以下命令创建它们:

keytool -genkey -alias myKeyPair -keyalg RSA -keysize 2048 store.jks

如果我查看密钥库,将会有一个 PrivateKeyEntry。接下来我创建证书请求:

keytool -certreq -keyalg RSA -alias myKeyPair -file request.csr -keystore store.jks

过了一会儿,我收到了签名的客户端证书 client.cer 和证书受信任的 CA ca.cer。 现在有问题:

首先,我尝试从 curl 发送请求。但是 curl 需要存储在 jks 中的私钥。我没有 openssl 也无法获取它,所以我使用 java 代码提取私钥。但结果总是一样的:istio gateway: peer did not return a certificate

其次,我尝试使用 java.net.http.HttpClient 和包含我的 jks 的 SSLContext 设置。它奏效了。但首先我必须把 ca.cerclient.cer 放在我的 jks 中。我不明白这一点:为什么我需要放 ca.cer?因为没有 ca.cer 存储在 store.jks 中,所以我有错误的证书验证。

另外,当我将 client.cer 放入 jks 时,keytool 会显示警告:Certificate already exists in keystore under alias <myKeyPair>. Do you still want to add it? 为什么它认为 privateKeyEntry 和 trustedCertEntry 相同?

Meta:由于问题含糊不清,回答不佳,但评论时间太长。

First, i tried to send request from curl. But curl needs private key which stored in jks. I dont have openssl and cant get it, so i extract private key using java code. But the result was always the same: istio gateway: peer did not return a certificate

要么是您的 'extract' 有误,要么是您提供给 curl 的方式有误,或者两者兼而有之,而您两者都没有描述。首先,要明确一点,就像 any 客户端进行客户端身份验证一样,curl 实际上需要私钥 and 证书,通常是任何适用的链证书.您必须使用什么文件格式,以及是单个组合文件还是单独文件(已添加:) 或 none 结果,取决于您使用的 curl 构建:curl supports seven SSL/TLS implementations, and the ways to provide client-key-and-cert vary among them. Use curl -V (uppercase) to see how it was built, then look at the portions of the man page, on your system or on the web ,适用于该实现。

Second, I tried using java.net.http.HttpClient with SSLContext setting containing my jks. And it worked. But firstly I had to put ca.cer and client.cer in my jks. And this I cannot understand: why do I need to put ca.cer? Because without ca.cer stored in store.jks i have error certificate validation.

可能是 'chain' 或中间 CA 证书。标准要求 SSL/TLS 客户端(如服务器)发送将 end-entity(客户端或服务器)证书连接​​到通常 'root' 所需的任何链证书接收者的信任库。 (从 RFC5280 开始,并由 RFC8446 确认,实际上可以使用不是根的锚点,但很少这样做。)它甚至可能是 combination链证书 根(或锚点)。 (一些依赖者有时仍然可以构建链来验证未正确发送的证书;浏览器尤其倾向于这样做,但大多数服务器没有。)

看看就知道了。如果它是 PEM 格式,您可以使用任何文本显示或编辑程序查看它包含多少证书。如果它是单个证书,您可以使用 keytool -printcert -file $file 显示详细信息——或者因为您已经导入了它,所以 keytool -list -v -alias name -keystore $ks [-storepass $pw]。如果它是 PEM 格式的多个证书,您可以使用编辑器将其分开并单独显示每个证书。如果它是 DER 格式的多个证书,您将无法轻松处理,但幸运的是这种格式很少使用。 openssl x509 [-inform pem|der] -text -noout也常用来显示cert文件的详细信息,但是你说不能用

Also when I put client.cer in jks, keytool displays a warning: Certificate already exists in keystore under alias . Do you still want to add it? Why does it think privateKeyEntry and trustedCertEntry are the same?

如果你只这样做了一次,而且是正确的,那不应该。给予单独的证书 文件,您应该 keytool -importcert 客户端 证书到您创建的私钥条目的别名,并用于创建 -certreq,在您的示例中是 myKeyPairkeytool -importcert任何需要的链证书,以及可选的根或锚点,(每个)到不同别名。 (使用 rootimedimed2 等简单词作为别名通常很方便,但不是必需的。)或者,如果您将整个链作为一个文件,PEM 序列或 DER 序列,或 'p7b'(没有数据和签名的虚拟 PKCS7 SignedData,通常用作一个或多个证书的容器,例如链)PEM 或 DER,您应该导入该链在一次操作中。