读取 PEM 证书链中的数据
Reading data in a PEM certificate chain
我可以使用以下内容轻松读取 PEM 格式的 x509 证书:
assets.open("ca.pem").use {
val cf = CertificateFactory.getInstance("X.509")
keystore.setCertificateEntry("server", cf.generateCertificate(it))
}
但是,我现在希望包括多个受信任的服务器证书。附加证书附加到 ca.pem
上,我使用声称读取多个证书的方法:
val certs = cf.generateCertificates(it)
但只有第一个证书被读入(certs
是大小 1)。
* <p>In the case of a certificate factory for X.509 certificates,
* <code>inStream</code> may contain a sequence of DER-encoded certificates
* in the formats described for
* {@link #generateCertificate(java.io.InputStream) generateCertificate}.
* In addition, <code>inStream</code> may contain a PKCS#7 certificate
* chain. This is a PKCS#7 <i>SignedData</i> object, with the only
* significant field being <i>certificates</i>. 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.
引用的部分:
* <p>In the case of a certificate factory for X.509 certificates, the
* certificate provided in <code>inStream</code> 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 看起来像:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
我是不是误解了证书工厂的用法?这可能是不支持标记的输入流的副作用(在这种情况下,整个流在第一个证书后被消耗)?也许换行符是不允许的,解析器将它们解释为数据结束。 PKCS7 会是比 PEM 更自然的选择吗?
确实,删除换行符会让解析器满意。
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
BouncyCastle's CertificateFactory
将忽略条目之间的空格:
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 可能会提供其他实用程序。
我可以使用以下内容轻松读取 PEM 格式的 x509 证书:
assets.open("ca.pem").use {
val cf = CertificateFactory.getInstance("X.509")
keystore.setCertificateEntry("server", cf.generateCertificate(it))
}
但是,我现在希望包括多个受信任的服务器证书。附加证书附加到 ca.pem
上,我使用声称读取多个证书的方法:
val certs = cf.generateCertificates(it)
但只有第一个证书被读入(certs
是大小 1)。
* <p>In the case of a certificate factory for X.509 certificates,
* <code>inStream</code> may contain a sequence of DER-encoded certificates
* in the formats described for
* {@link #generateCertificate(java.io.InputStream) generateCertificate}.
* In addition, <code>inStream</code> may contain a PKCS#7 certificate
* chain. This is a PKCS#7 <i>SignedData</i> object, with the only
* significant field being <i>certificates</i>. 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.
引用的部分:
* <p>In the case of a certificate factory for X.509 certificates, the
* certificate provided in <code>inStream</code> 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 看起来像:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
我是不是误解了证书工厂的用法?这可能是不支持标记的输入流的副作用(在这种情况下,整个流在第一个证书后被消耗)?也许换行符是不允许的,解析器将它们解释为数据结束。 PKCS7 会是比 PEM 更自然的选择吗?
确实,删除换行符会让解析器满意。
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
BouncyCastle's CertificateFactory
将忽略条目之间的空格:
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 可能会提供其他实用程序。