Concepts

In most cases,  we use a keystore and a truststore when our application needs to communicate over SSL/TLS .
在大多数情况下,当我们的应用程序需要通过 SSL/TLS 进行通信时,我们会使用密钥库和信任库。

Usually, these are password-protected files that sit on the same file system as our running application. The default format used for these files was  JKS until Java 8 .
通常,这些是受密码保护的文件,与我们正在运行的应用程序位于同一文件系统上。在 Java 8 之前,这些文件使用的默认格式是 JKS。

Since Java 9,  the default keystore format is PKCS12 . The biggest difference between JKS and PKCS12 is that JKS is a format specific to Java, while PKCS12 is a standardized and language-neutral way of storing encrypted private keys and certificates.
从 Java 9 开始,默认密钥库格式是 PKCS12。 JKS 和 PKCS12 之间的最大区别在于,JKS 是 Java 特有的格式,而 PKCS12 是存储加密私钥和证书的标准化且与语言无关的方式。

Java KeyStore

A Java keystore stores private key entries, certificates with public keys, or just secret keys  that we may use for various cryptographic purposes. It stores each by an alias for ease of lookup.
Java 密钥库存储私钥条目、带有公钥的证书,或者只是我们可用于各种加密目的的秘密密钥。它通过别名存储每个内容以便于查找。

Generally speaking, keystores hold keys that our application owns, which we can use to prove the integrity of a message and the authenticity of the sender, say by signing payloads.
一般来说,密钥库保存我们的应用程序拥有的密钥,我们可以用它来证明消息的完整性和发送者的真实性,例如通过签名有效负载。

Usually,  we’ll use a keystore when we’re a server and want to use HTTPS . During an SSL handshake, the server looks up the private key from the keystore, and presents its corresponding public key and certificate to the client.

Similarly, if the client also needs to authenticate itself, a situation called mutual authentication, then the client also has a keystore and also presents its public key and certificate.
类似地,如果客户端还需要对自己进行身份验证(这种情况称为相互身份验证),那么客户端也有一个密钥库,并且还提供其公钥和证书。

There’s no default keystore, so if we want to use an encrypted channel, we’ll have to set javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword. If our keystore format is different than the default, we could use javax.net.ssl.keyStoreType to customize it.
没有默认的密钥库,因此如果我们想使用加密通道,则必须设置 javax.net.ssl.keyStore 和 javax.net.ssl.keyStorePassword。如果我们的密钥库格式与默认值不同,我们可以使用 javax.net.ssl.keyStoreType 来自定义它。

Of course, we can use these keys to service other needs as well.  Private keys can sign or decrypt data, and public keys can verify or encrypt data. Secret keys can perform these functions as well. A keystore is a place that we can hold onto these keys.
当然,我们也可以使用这些键来满足其他需求。私钥可以签名或解密数据,公钥可以验证或加密数据。密钥也可以执行这些功能。密钥库是我们可以保存这些密钥的地方。

We can also interact with the keystore programmatically.

Java TrustStore

A truststore is the opposite. While a keystore typically holds onto certificates that identify us, a truststore holds onto certificates that identify others.
信任库则相反。密钥库通常保存用于识别我们身份的证书,而信任库则保存用于识别其他人的证书。

In Java, we use it to trust the third party we’re about to communicate with.

Take our earlier example. If a client talks to a Java-based server over HTTPS, the server will look up the associated key from its keystore and present the public key and certificate to the client.
以我们之前的例子为例。如果客户端通过 HTTPS 与基于 Java 的服务器通信,服务器将从其密钥库中查找关联的密钥,并将公钥和证书提供给客户端。

We, the client, then look up the associated certificate in our truststore.  If the certificate or Certificate Authorities presented by the external server isn’t in our truststore, we’ll get an SSLHandshakeException, and the connection won’t be set up successfully.
然后,我们(客户端)在我们的信任库中查找关联的证书。如果外部服务器提供的证书或证书颁发机构不在我们的信任库中,我们将收到 SSLHandshakeException,并且连接将无法成功建立。

Java has bundled a truststore called cacerts, and it resides in the _JAVA_HOME/jre/lib/security 目录中。

It contains default, trusted Certificate Authorities:
它包含默认的、受信任的证书颁发机构:

$ 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

We can see here that the truststore contains 92 trusted certificate entries and one of the entries is the verisignclass2gca entry_._ This means that the JVM will automatically trust certificates signed by verisignclass2g2ca.
我们可以在这里看到信任库包含 92 个受信任的证书条目,其中之一是 verisignclass2gca 条目。这意味着 JVM 将自动信任由 verisignclass2g2ca 签名的证书。

We can override the default truststore location via the javax.net.ssl.trustStore property . Similarly, we can set javax.net.ssl.trustStorePassword and javax.net.ssl.trustStoreType to specify the truststore’s password and type.
我们可以通过 javax.net.ssl.trustStore 属性覆盖默认的信任库位置。同样,我们可以设置 javax.net.ssl.trustStorePassword 和 javax.net.ssl.trustStoreType 来指定信任库的密码和类型。

What is a cacerts file?

The cacerts file is a collection of trusted certificate authority (CA) certificates. Sun Microsystems™ includes a cacerts file with its SSL support in the Java™ Secure Socket Extension (JSSE) tool kit and JDK 1.4.x. It contains certificate references for well-known Certificate authorities, such as VeriSign™. Its format is the “keystore” format defined by Sun. An administrator can edit the cacerts file with a command line tool (also provided by Sun) called keytool. For more information about keytool, see the Sun Web site.
cacerts 文件是受信任的证书颁发机构 (CA) 证书的集合。 Sun Microsystems™ 在 Java™ 安全套接字扩展 (JSSE) 工具包和 JDK 1.4.x 中包含一个 cacerts 文件及其 SSL 支持。它包含知名证书颁发机构(例如 VeriSign™)的证书参考。其格式是 Sun 定义的“keystore”格式。管理员可以使用名为 keytool 的命令行工具(也由 Sun 提供)编辑 cacerts 文件。有关 Java 的 keytool 工具的使keytool 简介 的更多信息,请访问 Sun 网站。

Note: The default password for the cacerts file supplied by Sun is changeit. You must use this password to view the contents or to import a new certificate. For security reasons, change the default password.
注意:Sun 提供的 cacerts 文件的默认密码是 changeit 。您必须使用此密码才能查看内容或导入新证书。出于安全原因,请更改默认密码。

The essential requirement is that the certificate authority that signed the HPE Service Manager server’s certificate must be in the list of certificate authorities named in this file. To use a self-issued server certificate created with OpenSSL or a tool such as Microsoft Certificate Server™, you must import the certificate for this private certificate authority into the cacerts file that the client uses for SSL. If you do not import the certificate, SSL connections fail because the Java SSL implementation does not recognize the certificate authority.
基本要求是签署 HPE Service Manager 服务器证书的证书颁发机构必须位于此文件中指定的证书颁发机构列表中。要使用通过 OpenSSL 或 Microsoft Certificate Server™ 等工具创建的自行颁发的服务器证书,您必须将此私有证书颁发机构的证书导入到客户端用于 SSL 的 cacerts 文件中。如果不导入证书,SSL 连接将失败,因为 Java SSL 实现无法识别证书颁发机构。