在java中从.p7b文件中提取单个.cer证书
我对密码学一无所知,所以如果你认为这是一个基本问题,请原谅 我有一个.p7b文件,我需要读取和提取单个公共证书,即.cer文件,并将其存储在密钥存储中。我不必担心密钥存储中的持久性,因为已经有一个服务将.cer文件作为字节[]接收并保存 我想知道的是,如何读取.p7b并提取单个.cer文件?我知道这可以通过openSSL命令来完成,但我需要在java中也这样做。我还需要读取由名称颁发的证书,因为它将用作持久化证书的唯一密钥在java中从.p7b文件中提取单个.cer证书,java,openssl,x509certificate,bouncycastle,pkcs#7,Java,Openssl,X509certificate,Bouncycastle,Pkcs#7,我对密码学一无所知,所以如果你认为这是一个基本问题,请原谅 我有一个.p7b文件,我需要读取和提取单个公共证书,即.cer文件,并将其存储在密钥存储中。我不必担心密钥存储中的持久性,因为已经有一个服务将.cer文件作为字节[]接收并保存 我想知道的是,如何读取.p7b并提取单个.cer文件?我知道这可以通过openSSL命令来完成,但我需要在java中也这样做。我还需要读取由名称颁发的证书,因为它将用作持久化证书的唯一密钥 提前感谢您可以使用BouncyCastle从PKCS#7对象获取证书。下
提前感谢您可以使用BouncyCastle从PKCS#7对象获取证书。下面是一个快速代码示例:
public Collection<X59Certificate> getCertificates(String path) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
CMSSignedData sd = new CMSSignedData(new FileInputStream(path));
X509Store store = sd.getCertificates("Collection", "BC");
Collection<X509Certificate> certificates = store.getMatches(X509CertStoreSelector.getInstance(new X509CertSelector()));
return certificates;
}
公共集合getCertificates(字符串路径)引发异常
{
addProvider(新的BouncyCastleProvider());
CMSSignedData sd=新的CMSSignedData(新文件输入流(路径));
X509Store=sd.getCertificates(“集合”、“BC”);
集合证书=store.getMatches(X509CertStoreSelector.getInstance(新的X509CertSelector());
退货证明书;
}
请注意,PKCS#7可能包含多个证书。大多数情况下,它包括在最终用户证书和根CA之间构建证书链所需的中间证书颁发机构证书。我成功地从p7b文件中读取了单个.X509证书。以下是步骤
- 第一步包括从java.io.File获取字节[]。这些步骤包括从文件中删除------BEGIN PKCS7------和------END PKCS7------,并解码剩余的base64编码字符串
BufferedReader reader = new BufferedReader(new FileReader(file)); StringBuilder cerfile = new StringBuilder(); String line = null; while(( line = reader.readLine())!=null){ if(!line.contains("PKCS7")){ cerfile.append(line); } } byte[] fileBytes = Base64.decode(cerfile.toString().getBytes());
- 下一步是使用BouncyCastleAPI解析文件
CMSSignedData dataParser = new CMSSignedData(trustBundleByte); ContentInfo contentInfo = dataParser.getContentInfo(); SignedData signedData = SignedData.getInstance(contentInfo.getContent()); CMSSignedData encapInfoBundle = new CMSSignedData(new CMSProcessableByteArray(signedData.getEncapContentInfo().getContent().getDERObject().getEncoded()),contentInfo); SignedData encapMetaData = SignedData.getInstance(encapInfoBundle.getContentInfo().getContent()); CMSProcessableByteArray cin = new CMSProcessableByteArray(((ASN1OctetString)encapMetaData.getEncapContentInfo().getContent()).getOctets()); CertificateFactory ucf = CertificateFactory.getInstance("X.509"); CMSSignedData unsignedParser = new CMSSignedData(cin.getInputStream()); ContentInfo unsginedEncapInfo = unsignedParser.getContentInfo(); SignedData metaData = SignedData.getInstance(unsginedEncapInfo.getContent()); Enumeration certificates = metaData.getCertificates().getObjects(); // Build certificate path while (certificates.hasMoreElements()) { DERObject certObj = (DERObject) certificates.nextElement(); InputStream bin = new ByteArrayInputStream(certObj.getDEREncoded()); X509Certificate cert = (X509Certificate) ucf.generateCertificate(bin); X500Name x500name = new JcaX509CertificateHolder(cert).getSubject(); RDN cn = x500name.getRDNs(BCStyle.CN)[0]; }
- 上面的步骤工作得很好,但我相信还有其他解决方案可以用更少的代码行来实现这一点。我使用的是bcjdk16罐
Enumeration certificates=dataParser.getCertificates().getObjects()代码>直接?