如何以正确的方式将 KeyPair 放入 KeyStore? (以编程方式在 Java 中)
How to put a KeyPair into a KeyStore the right way? (programmatically in Java)
最好展示我的问题并在之后解释它(我正在使用 KeyStore Explorer 来查看我的 .pfx 文件):
基本上,我想要右边的结果,但我得到了左边的结果。
更准确地说:KeyStore 应在一个条目中包含私钥和证书链 (KeyPair)。
我无法在 java 中使用它。这是我试图在左边得到的结果:
下面代码的问题是,它没有验证证书并将它们添加为受信任的证书。
/**
* Creates and returns a new {@link KeyStore} from the provided information.
* @param keystoreType The {@link KeyStore}s type. Recommended: "pkcs12".
* Check {@link KeyStore#getInstance(String)} for details.
* @param passwordAsCharArray Password to encrypt this {@link KeyStore} and its keys.
* @param certificateChain The certificate chain is simply an array of {@link X509Certificate}s.
* @param privateKey The {@link PrivateKey}.
* @param publicKey The {@link PublicKey}.
* @throws KeyStoreException
*/
public KeyStore buildAndGetKeystore(String keystoreType, char[] passwordAsCharArray,
X509Certificate[] certificateChain, PrivateKey privateKey, PublicKey publicKey)
throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException, EmptyStringException, EmptyCharArrayException, EmptyCertificateChainException {
// Check for null parameters
Objects.requireNonNull(keystoreType);
Objects.requireNonNull(passwordAsCharArray);
Objects.requireNonNull(certificateChain);
Objects.requireNonNull(privateKey);
Objects.requireNonNull(publicKey);
// Check for empty parameters
if (keystoreType.isEmpty()) throw new EmptyStringException("Parameter 'keystoreType' should NOT be empty!");
if (passwordAsCharArray.length==0) throw new EmptyCharArrayException("Parameter 'passwordAsCharArray' should NOT be empty!");
if (certificateChain.length==0) throw new EmptyCertificateChainException("Parameter 'certificateChain' should NOT be empty!");
// Initialise a new keystore
KeyStore keystore = KeyStore.getInstance(keystoreType);
keystore.load(null, passwordAsCharArray); // Pass null to tell java this is a new keystore
// Insert certificates
for (int i = 0; i < certificateChain.length; i++) {
keystore.setCertificateEntry(""+i, certificateChain[i]);
}
// Write private key (with password protection) to keystore.
// NOTE: I tried this before and it only writes
// the private key to the .pfx file and ignores the domain chain
//keystore.setKeyEntry("sso-signing-key", privateKey, passwordAsCharArray, certificateChain);
return keystore;
}
一些额外的细节:
右边的 KeyStore 是这样创建的:首先在 sslforfree.com 生成证书,然后使用 https://decoder.link/converter
将它们转换为 PKCS12 KeyStore
我创建了自己的证书链并将此结构用于证书链:
X509Certificate[] certificateChain = new X509Certificate[3];
certificateChain[0] = topCertificate;
certificateChain[1] = middleCertificate;
certificateChain[2] = rootCertificate;
密钥库创建部分就像这样简单(我省略了“notNull 检查”):
KeyStore keystore = KeyStore.getInstance(keystoreType);
keystore.load(null,null);
keystore.setKeyEntry("use_your_own_alias", privateKey, passwordAsCharArray, certificateChain);
return keystore;
请注意,公钥 不是 存储过程的一部分,因为它可用于
certificateChain[0].getPublicKey()
在 KeyStoreExplorer 中检查密钥库(我使用的是 PKCS12 密钥库)会得到以下输出:
和钥匙链:
你们不会相信这个,但是...问题是别名'priv-key'。刚刚删除了连字符 '-' 并将别名更改为 'myKey' 就像 中那样,瞧,它起作用了......
为这种愚蠢的事情浪费了这么多时间...
最好展示我的问题并在之后解释它(我正在使用 KeyStore Explorer 来查看我的 .pfx 文件):
基本上,我想要右边的结果,但我得到了左边的结果。
更准确地说:KeyStore 应在一个条目中包含私钥和证书链 (KeyPair)。
我无法在 java 中使用它。这是我试图在左边得到的结果: 下面代码的问题是,它没有验证证书并将它们添加为受信任的证书。
/**
* Creates and returns a new {@link KeyStore} from the provided information.
* @param keystoreType The {@link KeyStore}s type. Recommended: "pkcs12".
* Check {@link KeyStore#getInstance(String)} for details.
* @param passwordAsCharArray Password to encrypt this {@link KeyStore} and its keys.
* @param certificateChain The certificate chain is simply an array of {@link X509Certificate}s.
* @param privateKey The {@link PrivateKey}.
* @param publicKey The {@link PublicKey}.
* @throws KeyStoreException
*/
public KeyStore buildAndGetKeystore(String keystoreType, char[] passwordAsCharArray,
X509Certificate[] certificateChain, PrivateKey privateKey, PublicKey publicKey)
throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException, EmptyStringException, EmptyCharArrayException, EmptyCertificateChainException {
// Check for null parameters
Objects.requireNonNull(keystoreType);
Objects.requireNonNull(passwordAsCharArray);
Objects.requireNonNull(certificateChain);
Objects.requireNonNull(privateKey);
Objects.requireNonNull(publicKey);
// Check for empty parameters
if (keystoreType.isEmpty()) throw new EmptyStringException("Parameter 'keystoreType' should NOT be empty!");
if (passwordAsCharArray.length==0) throw new EmptyCharArrayException("Parameter 'passwordAsCharArray' should NOT be empty!");
if (certificateChain.length==0) throw new EmptyCertificateChainException("Parameter 'certificateChain' should NOT be empty!");
// Initialise a new keystore
KeyStore keystore = KeyStore.getInstance(keystoreType);
keystore.load(null, passwordAsCharArray); // Pass null to tell java this is a new keystore
// Insert certificates
for (int i = 0; i < certificateChain.length; i++) {
keystore.setCertificateEntry(""+i, certificateChain[i]);
}
// Write private key (with password protection) to keystore.
// NOTE: I tried this before and it only writes
// the private key to the .pfx file and ignores the domain chain
//keystore.setKeyEntry("sso-signing-key", privateKey, passwordAsCharArray, certificateChain);
return keystore;
}
一些额外的细节:
右边的 KeyStore 是这样创建的:首先在 sslforfree.com 生成证书,然后使用 https://decoder.link/converter
将它们转换为 PKCS12 KeyStore我创建了自己的证书链并将此结构用于证书链:
X509Certificate[] certificateChain = new X509Certificate[3];
certificateChain[0] = topCertificate;
certificateChain[1] = middleCertificate;
certificateChain[2] = rootCertificate;
密钥库创建部分就像这样简单(我省略了“notNull 检查”):
KeyStore keystore = KeyStore.getInstance(keystoreType);
keystore.load(null,null);
keystore.setKeyEntry("use_your_own_alias", privateKey, passwordAsCharArray, certificateChain);
return keystore;
请注意,公钥 不是 存储过程的一部分,因为它可用于
certificateChain[0].getPublicKey()
在 KeyStoreExplorer 中检查密钥库(我使用的是 PKCS12 密钥库)会得到以下输出:
和钥匙链:
你们不会相信这个,但是...问题是别名'priv-key'。刚刚删除了连字符 '-' 并将别名更改为 'myKey' 就像