Reading data in a PEM certificate chain
我可以使用以下内容轻松读取 PEM 格式的 x509 证书:
1 2 3 4 | assets.open("ca.pem").use { val cf = CertificateFactory.getInstance("X.509") keystore.setCertificateEntry("server", cf.generateCertificate(it)) } |
但是,我现在希望包含多个受信任的服务器证书。附加证书附加到
1 | val certs = cf.generateCertificates(it) |
但只读取第一个证书(
1 2 3 4 5 6 7 8 9 10 | * <p>In the case of a certificate factory for X.509 certificates, * <wyn>inStream</wyn> may contain a sequence of DER-encoded certificates * in the formats described for * {@link #generateCertificate(java.io.InputStream) generateCertificate}. * In addition, <wyn>inStream</wyn> may contain a PKCS#7 certificate * chain. This is a PKCS#7 SignedData object, with the only * significant field being certificates. In particular, the * signature and the contents are ignored. This format allows multiple * certificates to be downloaded at once. If no certificates are present, * an empty collection is returned. |
引用部分:
1 2 3 4 5 6 | * <p>In the case of a certificate factory for X.509 certificates, the * certificate provided in <wyn>inStream</wyn> must be DER-encoded and * may be supplied in binary or printable (Base64) encoding. If the * certificate is provided in Base64 encoding, it must be bounded at * the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at * the end by -----END CERTIFICATE-----. |
ca.pem 看起来像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- |
我是否误解了证书工厂的用法?这可能是不支持标记的输入流的副作用(在这种情况下,整个流在第一个证书之后被消耗)?也许换行是不允许的,解析器将它们解释为数据的结尾。 PKCS7 会比 PEM 更自然吗?
确实删除换行符会让解析器开心。
1 2 3 4 5 6 7 8 9 10 11 12 | -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- |
BouncyCastle 的
1 2 3 4 5 6 7 8 9 | import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory assets.open("ca.pem").use { pem -> val certreader = CertificateFactory() certreader.engineGenerateCertificates(pem) .forEach { cert -> keystore.setCertificateEntry("server", cert) } } |
我避免响应引用外部依赖项,但如果您在这个领域工作,Bouncy Castle 可能会提供其他实用程序。