简体   繁体   English

java http客户端如何验证服务器的CA证书?

[英]How does java http client validate Server's CA Certificate?

I am trying to understand SSL and reading different articles.我试图了解 SSL 并阅读不同的文章。 All articles have pictures like this( picture source ):所有文章都有这样的图片( 图片来源):

在此处输入图像描述

There are a lot of examples, but I want to understand step 3 If I use a browser, it's understandable.例子很多,但是我想了解第3步如果我使用浏览器,这是可以理解的。 The browser has itself mechanism for validation.浏览器有自己的验证机制。 But what if I use my java client?但是如果我使用我的 java 客户端呢? For example, I have an application that makes requests to - https://www.google.com/search?q=weather .例如,我有一个应用程序向 - https://www.google.com/search?q=weather发出请求。 How can I validate Google's Certificate?如何验证 Google 的证书? Should I do that?我应该这样做吗? Should I get this Certificate and add it to the trust store?我应该获取此证书并将其添加到信任库吗? Maybe I should add only not-public certificates to the trust store?也许我应该只将非公共证书添加到信任库?

Can anyone explain a chain of steps that java HTTP client makes for validation?谁能解释 java HTTP 客户端进行验证的一系列步骤? (You can use any java HTTP client for explanation) (您可以使用任何 java HTTP 客户端进行说明)

In step 2 the server provides his server certificate.在步骤 2 中,服务器提供他的服务器证书。 This is issued and signed by an official Certification Authority (CA, Root CA) like Baltimore Cypertrust, Entrust, DigiCert, Verisign, etc.这是由官方证书颁发机构(CA、根 CA)颁发和签署的,例如 Baltimore Cypertrust、Entrust、DigiCert、Verisign、etc。 or a Intermediate Certification Authority (ICA) whereby the certificate of an ICA is issued and signed by a root CA.或中间证书颁发机构 (ICA),ICA 的证书由根 CA 颁发和签名。

Before a CA/ICS issues a certificate it verifies that the requestor (aka subject) of a certificate is that person or company is who he pretends to be and is owner of the domain name the certificate should be issued for.在 CA/ICS 颁发证书之前,它会验证证书的请求者(即主体)是他假装的个人或公司,并且是应为其颁发证书的域名的所有者。

This builds a so called trust chain, from the server certificate backwards to a trusted authority.这构建了一个所谓的信任链,从服务器证书向后到受信任的机构。

In step 3 is verified that the certificate of step 2 lead to a known CA/ICA.在步骤 3 中验证步骤 2 的证书导致已知的 CA/ICA。 If so the certificate is accepted as trusted.如果是这样,则证书被接受为受信任的。 For this Java provides a store with all valid root and intermediate certificates of the certification authorities.为此,Java 提供了一个包含所有有效的证书颁发机构的根证书和中间证书的存储。

To list it's content, open a command shell, cange to the folder .../jre1.x.y_zzz/lib/security/ and type ../../bin/keytool.exe -keystore cacerts -list .要列出其内容,请打开命令 shell,转到文件夹.../jre1.x.y_zzz/lib/security/并键入../../bin/keytool.exe -keystore cacerts -list The question for a password can be skipped by pressing enter key.按回车键可以跳过密码问题。 Now you get a list of all certificates which are stored in the default store.现在您将获得存储在默认存储中的所有证书的列表。

dude@cs04n4 /cygdrive/c/Program Files/Java/jre1.8.0_301/lib/security
$ ../../bin/keytool.exe -keystore cacerts -list
Keystore-Kennwort eingeben:

*****************  WARNING WARNING WARNING  *****************
* Die Integrität der Informationen, die in Ihrem Keystore gespeichert sind, *
* wurde NICHT geprüft. Um die Integrität zu prüfen, *
* müssen Sie Ihr Keystore-Kennwort angeben.                  *
*****************  WARNING WARNING WARNING  *****************

Keystore-Typ: JKS
Keystore-Provider: SUN

Keystore enth▒lt 92 Eintr▒ge

sslrooteccca [jdk], 31.07.2020, trustedCertEntry,
Zertifikat-Fingerprint (SHA-256): 34:17:BB:06:CC:60:07:DA:1B:96:1C:92:0B:8A:B4:CE:3F:AD:82:0E:4A:A3:0B:9A:CB:C4:A7:4E:BD:CE:BC:65
digicertassuredidg3 [jdk], 25.08.2016, trustedCertEntry,
Zertifikat-Fingerprint (SHA-256): 7E:37:CB:8B:4C:47:09:0C:AB:36:55:1B:A6:F4:5D:B8:40:68:0F:BA:16:6A:95:2D:B1:00:71:7F:43:05:3F:C2
verisignuniversalrootca [jdk], 25.08.2016, trustedCertEntry,
Zertifikat-Fingerprint (SHA-256): 23:99:56:11:27:A5:71:25:DE:8C:EF:EA:61:0D:DF:2F:A0:78:B5:C8:06:7F:4E:82:82:90:BF:B8:60:E8:4B:3C
digicerttrustedrootg4 [jdk], 25.08.2016, trustedCertEntry,
Zertifikat-Fingerprint (SHA-256): 55:2F:7B:DC:F1:A7:AF:9E:6C:E6:72:01:7F:4F:12:AB:F7:72:40:C7:8E:76:1A:C2:03:D1:D9:D2:0A:C8:99:88
...
ttelesecglobalrootclass2ca [jdk], 25.08.2016, trustedCertEntry,
Zertifikat-Fingerprint (SHA-256): 91:E2:F5:78:8D:58:10:EB:A7:BA:58:73:7D:E1:54:8A:8E:CA:CD:01:45:98:BC:0B:14:3E:04:1B:17:05:25:52
addtrustqualifiedca [jdk], 25.08.2016, trustedCertEntry,
Zertifikat-Fingerprint (SHA-256): 80:95:21:08:05:DB:4B:BC:35:5E:44:28:D8:FD:6E:C2:CD:E3:AB:5F:B9:7A:99:42:98:8E:B8:F4:DC:D0:60:16
digicertglobalrootca [jdk], 25.08.2016, trustedCertEntry,
Zertifikat-Fingerprint (SHA-256): 43:48:A0:E9:44:4C:78:CB:26:5E:05:8D:5E:89:44:B4:D8:4F:96:62:BD:26:DB:25:7F:89:34:A4:43:C7:01:61

dude@cs04n4 /cygdrive/c/Program Files/Java/jre1.8.0_301/lib/security

When seting up a SSL connection you can either choose to use this default trust store or to use your own.设置 SSL 连接时,您可以选择使用此默认信任库或使用您自己的。 If you decide to use your own trust store you must create it and import the server / root certificates you trust.如果您决定使用自己的信任库,则必须创建它并导入您信任的服务器/根证书。

The whole Public Key Infrastructure (PKI) is needed to tell whether the guy who sent you data is actually that guy and not some man-in-the-middle.需要整个公钥基础设施 (PKI) 来判断向您发送数据的人是否真的是那个人,而不是中间人。 For this there should be some 3d-party (whom you trust) who checks whether the owner of the website and creates and signs a certificate for him.为此,应该有一些 3d 方(您信任的人)检查网站所有者是否为他创建和签署证书。 You can check that the certificate is valid because it's signed by CA and you trust that CA.您可以检查证书是否有效,因为它由 CA 签名并且您信任该 CA。

How do you set up whom to trust?你如何建立信任谁? You need to store a list somewhere.您需要在某处存储一个列表。 In case of Java the storage of trusted authorities and their public keys is in the file $JAVA_HOME/lib/security/cacerts .在 Java 的情况下,受信任机构及其公钥的存储在文件$JAVA_HOME/lib/security/cacerts中。 This file originally came from Java installation and it contains major CA's with certificates (yes, they will get expired at some point).该文件最初来自 Java 安装,它包含带有证书的主要 CA(是的,它们会在某个时候过期)。 This file can be modified (CA certificates can be added or removed) with a keytool utility which comes with Java.可以使用 Java 附带的keytool实用程序修改此文件(可以添加或删除 CA 证书)。

Now it's a bit more complicated because CA have levels of certificates: there's a Root cert which is used to sign Intermediate certs, which then are used to sign site owner's certificate.现在它有点复杂,因为 CA 具有证书级别:有一个根证书用于签署中间证书,然后用于签署站点所有者的证书。 When your Java code needs to communicate using TLS/SSL it needs to:当您的 Java 代码需要使用 TLS/SSL 进行通信时,它需要:

  1. Download site's certificate下载网站的证书
  2. Check that it's signed by a trusted CA检查它是否由受信任的 CA 签名

But while site's cert is signed by Intermediate cert, we don't always store it in cacerts .但是,虽然站点的证书是由中间证书签名的,但我们并不总是将它存储在cacerts中。 Usually only the Root certificate is stored.通常只存储根证书。 In such case there are 2 choices - either add Intermediate cert to cacerts (bad solution) or the website's owner needs to set up a certificate chain which will include both his cert, the cert that signed him, the cert that signed that one and so on until it reacher the Root.在这种情况下,有两种选择 - 要么将中间证书添加到cacerts (错误的解决方案),要么网站所有者需要建立一个证书链,其中包括他的证书、签署他的证书、签署该证书的证书等等直到它到达根。 In this set up as long as you can check any certificate in this chain - you will trust that website.在此设置中,只要您可以检查此链中的任何证书 - 您就会信任该网站。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM