gpt4 book ai didi

java - 以编程方式将 PEM 证书导入 Java KeyStore

转载 作者:太空宇宙 更新时间:2023-11-03 13:14:19 26 4
gpt4 key购买 nike

我有一个由两个文件(.crt 和 .key)组成的客户端证书,我希望将其导入到 java KeyStore 中,然后在 SSLContext 中使用以通过 Apache 的 HTTPClient 发送 HTTP 请求。但是,我似乎找不到以编程方式执行此操作的方法,我发现的大多数其他问题要么指向外部工具,要么不适合我的情况。

我的证书使用典型的“BEGIN CERTIFICATE”编码,后跟 Base64 编码字符串, key 使用“BEGIN RSA PRIVATE KEY”,然后是另一个 Base64 编码字符串。

这是我到目前为止得到的:

private static SSLContext createSSLContext(File certFile, File keyFile) throws IOException {
try {
PEMParser pemParser = new PEMParser(new FileReader(keyFile));
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(new BouncyCastleProvider());
Object object = pemParser.readObject();
KeyPair kp = converter.getKeyPair((PEMKeyPair) object);
PrivateKey privateKey = kp.getPrivate();

CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
FileInputStream stream = new FileInputStream(certFile);
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(stream);

KeyStore store = KeyStore.getInstance("JKS");
store.load(null);
store.setCertificateEntry("certificate", cert);
store.setKeyEntry("private-key", privateKey, "changeit".toCharArray(), new Certificate[] { cert });

SSLContext sslContext = SSLContexts.custom()
.loadKeyMaterial(store, "changeit".toCharArray())
.build();
return sslContext;
} catch (IOException | NoSuchAlgorithmException | CertificateException | KeyStoreException | KeyManagementException | UnrecoverableKeyException e) {
throw new IOException(e);
}
}

堆栈跟踪:

java.io.IOException: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format at me.failedshack.ssltest.SSLTest.createSSLContext(SSLTest.java:80) at me.failedshack.ssltest.SSLTest.main(SSLTest.java:31)

Caused by: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:216) at java.base/java.security.KeyFactory.generatePrivate(KeyFactory.java:390) at me.failedshack.ssltest.SSLTest.createSSLContext(SSLTest.java:62) ... 1 more

Caused by: java.security.InvalidKeyException: invalid key format at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:330) at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:355) at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.(RSAPrivateCrtKeyImpl.java:91) at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75) at java.base/sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:315) at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:212) ... 3 more

遗憾的是,从文件生成私钥时,我不断收到 InvalidKeyException。

最佳答案

RSA PRIVATE KEY 类型的 PEM 文件是 base64 而非二进制,更重要的是采用 PKCS1 格式而非 PKCS8,因此不能作为 PKCS8EncodedKeySpec 进行处理。

您的选择是:

  • 将 PKCS1 PEM 格式转换为 PKCS8(未加密)PEM 格式;阅读并删除标题和结尾行并将 base64 解码为二进制并将其放入 PKCS8EncodedKeySpec - 但您说您不需要外部工具,而且转换私钥 PLUS 也很容易将证书(或链)转换为 已经 Java keystore 的 PKCS12 (DER) 并避免该问题

  • 将 PKCS1 PEM 格式转换为 PKCS8(未加密)DER 格式,您可以将其作为二进制文件读取并放入 PKCS8EncodedKeySpec -- 同上

  • 如果 PKCS1 PEM 未加密,请按上述方式读取并解码为 PKCS1 DER,然后手动构建 PKCS8(未加密)编码,并使用它

  • 如果 PKCS1 PEM 已加密,您可以检测到这一点,因为它的主体除了 base64 之外还包含两个 822 样式的标题行,您必须复制 OpenSSL 的“遗留” key 文件解密,加上构建 PKCS8 (未加密)编码

  • 如果你可以专门使用BouncyCaSTLebcpkix,它可以直接读取和解析所有OpenSSL用于私钥的PEM变体,包括对加密的进行解密;但是,如果您还没有使用它,那么这是一个额外的 jar 来安装和/或部署

看看这些骗局中的一个或多个:
Load certificate to KeyStore (JAVA) (Q使用BouncyCaSTLe构建PKCS8)
Java: Convert DKIM private key from RSA to DER for JavaMail (我的回答是“手工”构建 PKCS8)
How to Load RSA Private Key From File (使用 BouncyCaSTLe 读取)
Read RSA private key of format PKCS1 in JAVA (使用 BouncyCaSTLe 读取)
Get a PrivateKey from a RSA .pem file (使用BC解密)
Decrypting an OpenSSL PEM Encoded RSA private key with Java? (手动解密)
也许 PKCS#1 and PKCS#8 format for RSA private key (背景)
Differences between "BEGIN RSA PRIVATE KEY" and "BEGIN PRIVATE KEY" (背景)

关于java - 以编程方式将 PEM 证书导入 Java KeyStore,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51352762/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com