Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java客户端证书和密钥库_Java_Ssl_Https_Ssl Certificate - Fatal编程技术网

Java客户端证书和密钥库

Java客户端证书和密钥库,java,ssl,https,ssl-certificate,Java,Ssl,Https,Ssl Certificate,我们正在尝试建立一种双向认证机制 因为我们访问了两个不同的主机,所以在客户端密钥库容器中存储了两个不同别名下的相同客户端证书(请注意相同的指纹): 现在,在受信任容器下,我们有了目标域证书(请注意它们之间的指纹是如何不同的,并且与上面的密钥库进行了比较): 我的理解是,如果您必须存储一个别名与目标域名匹配的证书(在我们的例子中是i.domain.io或r.domain.io),那么当您尝试SSL连接到该域时,java可以将相关证书作为客户端证书提供,例如 我们正在像这样发布我们的应用程序: ja

我们正在尝试建立一种双向认证机制

因为我们访问了两个不同的主机,所以在客户端密钥库容器中存储了两个不同别名下的相同客户端证书(请注意相同的指纹):

现在,在受信任容器下,我们有了目标域证书(请注意它们之间的指纹是如何不同的,并且与上面的密钥库进行了比较):

我的理解是,如果您必须存储一个别名与目标域名匹配的证书(在我们的例子中是i.domain.io或r.domain.io),那么当您尝试SSL连接到该域时,java可以将相关证书作为客户端证书提供,例如

我们正在像这样发布我们的应用程序:

java    -Djavax.net.debug=all \
        -Djavax.net.ssl.keyStore=/opt/golem/client.keystore \
        -Djavax.net.ssl.keyStorePassword=_____ \
        -Djavax.net.ssl.trustStore=/opt/golem/trusted.keystore \
        -Djavax.net.ssl.trustStorePassword=_____ \
我们的问题是,没有提供客户端证书,也没有从客户端使用客户端证书。因此,最大的问题是java是否提供与匹配目标域名(或目标SSL证书中的主题行)的别名相关联的客户端证书,或者证书的名称应该从代码中删除

我的理解是,如果您必须存储一个别名与目标域名匹配的证书(在我们的例子中是i.domain.io或r.domain.io),那么当您尝试SSL连接到该域时,java可以将相关证书作为客户端证书提供,例如
https://r.domain.io

事实并非如此

匹配基于(发卡机构)和密钥类型(如RSA或DSA)。如果属性不完全符合预期,则可以选择一些不完美的匹配(请参阅),但您至少希望由服务器播发的CA颁发客户端证书(这通常是在服务器端配置CA证书时自动完成的,除非您在服务器端明确更改配置)

如果需要中级证书,您一定要确保您已获得

本质上,在密钥库中拥有两次相同的证书是没有意义的

(您可以尝试通过扩展自己的
X509KeyManager
来强制使用特定别名,但这还不够;特别是,这不会使服务器请求它,也不会使链有效。)

您需要确保服务器配置为请求证书。这有时可以通过重新协商完成,因此使用Wireshark可能不一定可以看到
CertificateRequest
TLS消息。但是,您应该能够使用
-Djavax.net.debug=ssl
(或
all
)从客户端看到它:如果您在页面上搜索
CertificateRequest
,则有一个示例

然后,您需要确保您的证书(或客户端上链的顶部,如果有中间证书)是由该
CertificateRequest
消息中公布的CA之一颁发的(颁发者DN必须匹配)


(如果
CertificateRequest
中的证书颁发机构列表为空,但仍发送
CertificateRequest
消息,则默认情况下,客户端将发送在其密钥库中找到的第一个证书。这种情况是不典型的,因为它通常需要在服务器端进行自定义配置。)

别名与目标域没有任何关系。您不需要相同证书的多个副本。这里还有一个问题。如果证书颁发机构:您是否可以通过客户端证书?是的,这是我在最后一句中说的:它将发送找到的第一个证书(如果密钥库中只有一个密钥,那么这应该不会是问题)。服务器仍需要发送该证书请求,证书是否被接受取决于服务器的实现和配置。它肯定需要一种方法以某种方式验证该证书。Bruno,还有一个问题:客户端是否完全有必要在证书发出后使用/提供私钥服务器回复CertificateRequest?客户端确实向服务器提供私钥,但它确实需要使用私钥来完成握手(对
证书验证
消息的内容进行签名)。没有私钥,就不会进行身份验证(否则证书是公开的)@Bruno您的意思是客户端不向服务器提供私钥。
root@perf-golem-4:/opt/golem# keytool -list -keystore ./trusted.keystore -storepass _______

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

i.domain.io, Jun 16, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): 73:F5:96:68:89:56:5E:50:9C:06:69:67:AC:8E:18:D2:D9:C1:33:71
r.domain.io, Jun 16, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): 12:93:C8:41:3F:68:22:8F:40:F8:3C:B9:B6:C4:90:C0:60:49:D0:50
java    -Djavax.net.debug=all \
        -Djavax.net.ssl.keyStore=/opt/golem/client.keystore \
        -Djavax.net.ssl.keyStorePassword=_____ \
        -Djavax.net.ssl.trustStore=/opt/golem/trusted.keystore \
        -Djavax.net.ssl.trustStorePassword=_____ \