在 Java 中使用 BouncyCastle 从 PKCS7 PEM 格式证书创建 X509Certificate
Create X509Certificate from PKCS7 PEM formatted certificate using BouncyCastle in Java
我有 PEM 格式的 PKCS7 证书链。基本上我想使用 BouncyCastle 库在 Java 中执行以下 openssl 命令。
openssl pkcs7 -in client-certificate_pkcs7.pem -out client-certificate_chain.pem
我正在关注 BouncyCastle (https://www.bouncycastle.org/fips-java/BCFipsIn100.pdf) 提供的这个 pdf,但找不到真正满足我需要的任何东西。
我发现 CMSSignedData 用于 BouncyCastle 中的 pkcs7 相关操作,所以我尝试使用它,但出现错误,我认为这是因为我使用的是原始字符串。
String pkcs7Pem = "-----BEGIN PKCS7-----\nMIIR...WTEA\n-----END PKCS7-----\n";
CMSSignedData data = new CMSSignedData(pkcs7Pem.getBytes());
Store certStore = data.getCertificates();
SignerInformationStore signerInfos = data.getSignerInfos();
Collection<SignerInformation> signers = signerInfos.getSigners();
List<X509Certificate> x509Certificates = new ArrayList<>();
for (SignerInformation signer : signers) {
Collection<X509CertificateHolder> matches = certStore.getMatches(signer.getSID());
for (X509CertificateHolder holder : matches) {
x509Certificates.add(new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder));
}
}
这是我在 new CMSSignedData(pkcs7Pem.getBytes());
上遇到的错误
org.bouncycastle.cms.CMSException: IOException reading content.
我也尝试过使用 PEMParser
,但是 returns 下的 parser.readObject()
无效。
String pkcs7Pem = "-----BEGIN PKCS7-----\nMIIR...WTEA\n-----END PKCS7-----\n";
PEMParser parser = new PEMParser(new StringReader(pkcs7Pem));
parser.readObject();
如有任何帮助,我们将不胜感激!
openssl pkcs7 -in client-certificate_pkcs7.pem -out client-certificate_chain.pem
该命令仅将其输入(如果它是 PKCS7 PEM)复制到其输出而不做任何更改。这没有用,您也不需要 BouncyCastle 在 Java 中做同样的事情。我怀疑你的意思是
openssl pkcs7 -print_certs -in (pkcs7) -out (chain)
提取单个证书,作为一系列单独的 (PEM) 对象。
I’ve found that CMSSignedData is used for pkcs7 related operations in BouncyCastle
只有一些 -- 有 很多 种 PKCS7/CMS 格式和操作可以完成,还有很多不同的 BC classes 可以完成它们.但是用于携带证书链的 PKCS7/CMS 格式,通常标记为 p7b 或 p7c,是 SignedData 类型,由 BouncyCastle CMSSignedData
class.
实现
I also have tried using PEMParser, but parser.readObject() below returns null.
它不应该,如果你给它有效 PEM 输入不是你发布的损坏版本。对我来说,如果我给它一个包含 p7b/c 证书链的有效 PEM PKCS7,我会得到一个 ContentInfo
,然后可以按如下方式对其进行解码(为方便起见,我使用文件 I/O,但任何 Java Reader
和 Writer
的效果相同):
static void SO70048115PKCS7Certs (String[] args) throws Exception {
PEMParser p = new PEMParser(new FileReader(args[0]));
CMSSignedData sd = new CMSSignedData( (ContentInfo)p.readObject() );
p.close();
JcaPEMWriter w = new JcaPEMWriter(new FileWriter(args[1]));
for( X509CertificateHolder ch : sd.getCertificates().getMatches(null) ){
// optionally put subject,issuer as 'comments' like OpenSSL does
w.writeObject( new PemObject("CERTIFICATE",ch.getEncoded()) );
}
w.close();
}
注意 p7b/c 按照惯例不包含任何签名(在 PKCS7/CMS 术语中,SignerInfo(s))所以您发布的代码 - 旨在查找证书(s) 与签名相关联 -- 不合适且无效。您只需要使用证书而不需要任何 SignerInfo。
我有 PEM 格式的 PKCS7 证书链。基本上我想使用 BouncyCastle 库在 Java 中执行以下 openssl 命令。
openssl pkcs7 -in client-certificate_pkcs7.pem -out client-certificate_chain.pem
我正在关注 BouncyCastle (https://www.bouncycastle.org/fips-java/BCFipsIn100.pdf) 提供的这个 pdf,但找不到真正满足我需要的任何东西。
我发现 CMSSignedData 用于 BouncyCastle 中的 pkcs7 相关操作,所以我尝试使用它,但出现错误,我认为这是因为我使用的是原始字符串。
String pkcs7Pem = "-----BEGIN PKCS7-----\nMIIR...WTEA\n-----END PKCS7-----\n";
CMSSignedData data = new CMSSignedData(pkcs7Pem.getBytes());
Store certStore = data.getCertificates();
SignerInformationStore signerInfos = data.getSignerInfos();
Collection<SignerInformation> signers = signerInfos.getSigners();
List<X509Certificate> x509Certificates = new ArrayList<>();
for (SignerInformation signer : signers) {
Collection<X509CertificateHolder> matches = certStore.getMatches(signer.getSID());
for (X509CertificateHolder holder : matches) {
x509Certificates.add(new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder));
}
}
这是我在 new CMSSignedData(pkcs7Pem.getBytes());
org.bouncycastle.cms.CMSException: IOException reading content.
我也尝试过使用 PEMParser
,但是 returns 下的 parser.readObject()
无效。
String pkcs7Pem = "-----BEGIN PKCS7-----\nMIIR...WTEA\n-----END PKCS7-----\n";
PEMParser parser = new PEMParser(new StringReader(pkcs7Pem));
parser.readObject();
如有任何帮助,我们将不胜感激!
openssl pkcs7 -in client-certificate_pkcs7.pem -out client-certificate_chain.pem
该命令仅将其输入(如果它是 PKCS7 PEM)复制到其输出而不做任何更改。这没有用,您也不需要 BouncyCastle 在 Java 中做同样的事情。我怀疑你的意思是
openssl pkcs7 -print_certs -in (pkcs7) -out (chain)
提取单个证书,作为一系列单独的 (PEM) 对象。
I’ve found that CMSSignedData is used for pkcs7 related operations in BouncyCastle
只有一些 -- 有 很多 种 PKCS7/CMS 格式和操作可以完成,还有很多不同的 BC classes 可以完成它们.但是用于携带证书链的 PKCS7/CMS 格式,通常标记为 p7b 或 p7c,是 SignedData 类型,由 BouncyCastle CMSSignedData
class.
I also have tried using PEMParser, but parser.readObject() below returns null.
它不应该,如果你给它有效 PEM 输入不是你发布的损坏版本。对我来说,如果我给它一个包含 p7b/c 证书链的有效 PEM PKCS7,我会得到一个 ContentInfo
,然后可以按如下方式对其进行解码(为方便起见,我使用文件 I/O,但任何 Java Reader
和 Writer
的效果相同):
static void SO70048115PKCS7Certs (String[] args) throws Exception {
PEMParser p = new PEMParser(new FileReader(args[0]));
CMSSignedData sd = new CMSSignedData( (ContentInfo)p.readObject() );
p.close();
JcaPEMWriter w = new JcaPEMWriter(new FileWriter(args[1]));
for( X509CertificateHolder ch : sd.getCertificates().getMatches(null) ){
// optionally put subject,issuer as 'comments' like OpenSSL does
w.writeObject( new PemObject("CERTIFICATE",ch.getEncoded()) );
}
w.close();
}
注意 p7b/c 按照惯例不包含任何签名(在 PKCS7/CMS 术语中,SignerInfo(s))所以您发布的代码 - 旨在查找证书(s) 与签名相关联 -- 不合适且无效。您只需要使用证书而不需要任何 SignerInfo。