Keystore.setKeyEntry() 中的 Certificate[] 链是什么意思以及如何从 JKS 或 PKCS12 获取该信息?
What does the Certificate[] chain in the Keystore.setKeyEntry() mean and how to obtain that info from a JKS or PKCS12?
我知道什么是证书链。在 java 使用 KeyStore 对象时,我们可以将证书和私钥添加到密钥库对象。
我们这样做:
KeyStore sourceKeystore = KeyStore.getInstance("jks");
try (InputStream stream = new BufferedInputStream(Files.newInputStream(sourceKeystorePath))) {
sourceKeystore.load(stream, sourceKeystorePassword);
}
KeyStore destKeystore = KeyStore.getInstance("jks");
destKeystore.load(null, destKeystorePassword);
Enumeration<String> aliasList = sourceKeystore.aliases();
while (aliasList.hasMoreElements()) {
String alias = aliasList.nextElement();
destKeystore.setCertificateEntry(alias, sourceKeystore.getCertificate(alias));
if(sourceKeystore.isKeyEntry(alias)) {
System.out.println(alias + " : is private key");
Key key = sourceKeystore.getKey(alias, "secret".toCharArray());
Certificate[] chain = new Certificate[1];
chain[0] = sourceKeystore.getCertificate(alias);
destKeystore.setKeyEntry(alias, key, "secret".toCharArray(), chain);
}
}
try (OutputStream stream = new BufferedOutputStream(Files.newOutputStream(destKeystorePath))) {
destKeystore.store(stream, destKeystorePassword);
}
我想了解的是destKeystore.setKeyEntry()
。当我在此提供证书链作为参数时,我可以提供这样的证书数组吗?
- [rootCert、interCert、mainCert]
- [mainCert、interCert、rootCert]
- [mainCert]
第一个问题: 这些不同的上链方式是什么意思?
第二个问题: 另外如果我有JKS文件。我如何找到证书链的确切值以及证书链在此 KeyStore 中为私钥设置的顺序?基本上我的意思是我想找出在那个 JKS 文件
中传递给 KeyStore.setKeyEntry() 的 Certificate[] 参数是什么
首先,证书链是如何形成的基础知识。
当您最初通过任何方式(keytool、openssl 等)创建 key pair
时,它基本上由与其 self-signed certificate
关联的 private key
组成,其中 self-signed 证书包含 public key
。然后 PKCS#10
(certificate signing request) 从 key-pair 中创建出来,这基本上是关于私钥所有者的一些身份信息 + public 密钥,放在一起并由私钥签名。此 CSR 将发送到 Certificate Authority
以取回签名证书。 CA 对其进行签名并使用证书链进行响应。然后将收到的证书链更新为最初创建的私钥,替换旧的 self-signed 证书。现在,我们称这个密钥对为签名密钥对,它不再是self-signed。
现在了解 CA 发送的内容。 CA 发送的证书链基本上是这样的:
CA Certificate (self-signed)
|
|__ 2. Sub CA Certificate (signed by the above CA)
|
|__ 1. Sub-sub CA Certificate (if any) (signed by the above Sub CA)
|
|__ 0. End Entity Certificate (your certificate, signed by the above cert)
如果您查看证书的索引,它们会告诉您以下内容:
- 最重要的证书是第一个证书(也就是 user/peer 证书)
- 最不重要的证书是最后一个证书(又名 CA 证书)
在编码术语中,证书数组的第一个(第零个)元素是用户证书,证书数组的最后一个元素是 CA 证书。也就是说,属于你的私钥的匹配 public 密钥可以在第一个证书中找到。
99% 的时间您不必自己处理证书链的顺序。当 CA 以证书链响应时,通常顺序是正确的。您所要做的就是将证书链更新为您的私钥。
现在回答您的问题:
- 由于您在 java 世界中,证书的第一个顺序被认为是倒序的(不正确)。第二个选项是正确的。第三个选项也是正确的,但如果您有的话,建议始终包含整个证书链。
- 在你正在做的代码中:
Certificate[] chain = new Certificate[1];
chain[0] = sourceKeystore.getCertificate(alias);
destKeystore.setKeyEntry(alias, key, "secret".toCharArray(), chain);
还有一种方法可用于 return 您与私钥 getCertificateChain() 关联的整个证书链。你可以在哪里做:
Certificate[] chain = sourceKeystore.getCertificateChain(alias);
destKeystore.setKeyEntry(alias, key, "secret".toCharArray(), chain);
数组 getCertificateChain()
return 的顺序是最初设置的顺序。
我知道什么是证书链。在 java 使用 KeyStore 对象时,我们可以将证书和私钥添加到密钥库对象。
我们这样做:
KeyStore sourceKeystore = KeyStore.getInstance("jks");
try (InputStream stream = new BufferedInputStream(Files.newInputStream(sourceKeystorePath))) {
sourceKeystore.load(stream, sourceKeystorePassword);
}
KeyStore destKeystore = KeyStore.getInstance("jks");
destKeystore.load(null, destKeystorePassword);
Enumeration<String> aliasList = sourceKeystore.aliases();
while (aliasList.hasMoreElements()) {
String alias = aliasList.nextElement();
destKeystore.setCertificateEntry(alias, sourceKeystore.getCertificate(alias));
if(sourceKeystore.isKeyEntry(alias)) {
System.out.println(alias + " : is private key");
Key key = sourceKeystore.getKey(alias, "secret".toCharArray());
Certificate[] chain = new Certificate[1];
chain[0] = sourceKeystore.getCertificate(alias);
destKeystore.setKeyEntry(alias, key, "secret".toCharArray(), chain);
}
}
try (OutputStream stream = new BufferedOutputStream(Files.newOutputStream(destKeystorePath))) {
destKeystore.store(stream, destKeystorePassword);
}
我想了解的是destKeystore.setKeyEntry()
。当我在此提供证书链作为参数时,我可以提供这样的证书数组吗?
- [rootCert、interCert、mainCert]
- [mainCert、interCert、rootCert]
- [mainCert]
第一个问题: 这些不同的上链方式是什么意思?
第二个问题: 另外如果我有JKS文件。我如何找到证书链的确切值以及证书链在此 KeyStore 中为私钥设置的顺序?基本上我的意思是我想找出在那个 JKS 文件
中传递给 KeyStore.setKeyEntry() 的 Certificate[] 参数是什么首先,证书链是如何形成的基础知识。
当您最初通过任何方式(keytool、openssl 等)创建 key pair
时,它基本上由与其 self-signed certificate
关联的 private key
组成,其中 self-signed 证书包含 public key
。然后 PKCS#10
(certificate signing request) 从 key-pair 中创建出来,这基本上是关于私钥所有者的一些身份信息 + public 密钥,放在一起并由私钥签名。此 CSR 将发送到 Certificate Authority
以取回签名证书。 CA 对其进行签名并使用证书链进行响应。然后将收到的证书链更新为最初创建的私钥,替换旧的 self-signed 证书。现在,我们称这个密钥对为签名密钥对,它不再是self-signed。
现在了解 CA 发送的内容。 CA 发送的证书链基本上是这样的:
CA Certificate (self-signed)
|
|__ 2. Sub CA Certificate (signed by the above CA)
|
|__ 1. Sub-sub CA Certificate (if any) (signed by the above Sub CA)
|
|__ 0. End Entity Certificate (your certificate, signed by the above cert)
如果您查看证书的索引,它们会告诉您以下内容:
- 最重要的证书是第一个证书(也就是 user/peer 证书)
- 最不重要的证书是最后一个证书(又名 CA 证书)
在编码术语中,证书数组的第一个(第零个)元素是用户证书,证书数组的最后一个元素是 CA 证书。也就是说,属于你的私钥的匹配 public 密钥可以在第一个证书中找到。
99% 的时间您不必自己处理证书链的顺序。当 CA 以证书链响应时,通常顺序是正确的。您所要做的就是将证书链更新为您的私钥。
现在回答您的问题:
- 由于您在 java 世界中,证书的第一个顺序被认为是倒序的(不正确)。第二个选项是正确的。第三个选项也是正确的,但如果您有的话,建议始终包含整个证书链。
- 在你正在做的代码中:
Certificate[] chain = new Certificate[1]; chain[0] = sourceKeystore.getCertificate(alias); destKeystore.setKeyEntry(alias, key, "secret".toCharArray(), chain);
还有一种方法可用于 return 您与私钥 getCertificateChain() 关联的整个证书链。你可以在哪里做:
Certificate[] chain = sourceKeystore.getCertificateChain(alias); destKeystore.setKeyEntry(alias, key, "secret".toCharArray(), chain);
数组 getCertificateChain()
return 的顺序是最初设置的顺序。