java如何读取OkHttpClient的证书链
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] keyBytes = Files.readAllBytes((Paths.get("/path/to/chain.pem")));
X509EncodedKeySpec spec =
new X509EncodedKeySpec(keyBytes);
PublicKey publicKey = keyFactory.generatePublic(spec);
byte[] privateKeyBytes = Files.readAllBytes(Paths.get("/path/to/key.pem"));
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
HeldCertificate cert = new HeldCertificate.Builder().keyPair(publicKey, privateKey).build();
HandshakeCertificates clientCertificates = new HandshakeCertificates.Builder()
.heldCertificate(cert)
.build();
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
.build();
我正在尝试使用Okhttpclient进行客户端身份验证,这就是我目前拥有的。链条。pem文件具有多个形式证书
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
钥匙工厂。generatePublic方法在尝试解析证书链时失败,返回Caused by: java.security.InvalidKeyException: invalid key format
。如何为OkhttpClient解析此证书链?我是否必须将链拆分为多个PEM
# 1 楼答案
这些是证书,而不是一个或几个公钥。证书包含公钥,但该证书不是公钥,不能作为公钥读取。此外,向您颁发这些证书是有原因的;如果您使用提供的证书链(和私钥),服务器将信任它们,但如果您生成自己的自签名证书,即使是相同的密钥,这也是您的
HeldCertificate.Builder()
将要做的,服务器将不信任该证书,因为它不是由有效的CA颁发的。数字证书有时类似于护照;如果你有一本护照,上面有你的姓名和照片,是由你的政府签发的,其他国家(以及国内实体)通常会接受它作为你身份的证明,但是如果你在一张纸上写上你的姓名和“passport”一词,然后贴上你自己的照片,没有人会接受这一点作为自我签名证书的证明用Java读取文件相当容易。证书的格式最简单,可以由
CertificateFactory
直接读取:关键可能更难;如果它是PEM格式,如名称
key.pem
所示KeyFactory
(不同于CertificateFactory
),则不读取PEM。如果它是一种特殊的PEM格式,即PKCS8未加密,按照-BEGIN PRIVATE KEY -
和类似的END
标记的RFC7468 section 10和类似的END
,在开始/结束和私钥之间没有其他单词,则可以如下转换它:然而,至少还有十几种其他PEM格式用于私有密钥,Java无法直接读取其中大多数由OpenSSL使用,如果
BEGIN
和END
行表示ENCRYPTED PRIVATE KEY
或{RSA|DSA|EC} PRIVATE KEY
,则可以使用openssl
命令行将其转换为Java可以处理的格式:此外,如果您将
-outform der
添加到其中任何一个(请相应地更改文件名以避免混淆),则不再需要de PEM步骤,您可以将Files.readAllBytes
结果直接放入PKCS8EncodedKeySpec
。如果您的密钥文件是其他文件,则更难或可能不可能;你必须提供更多的细节在OkHttp中使用坦白地说this API在我看来,它是由不知道自己在做什么的人设计的;将
KeyPair
与Certificate
一起使用毫无意义。但从逻辑上讲,这应该起作用: