簡體   English   中英

從java中的.p7b文件中提取單個.cer證書

[英]Extracting individual .cer certificate from a .p7b file in java

我是Cryptography的新手,所以如果您認為這是一個基本問題,請原諒

我有一個.p7b文件,我需要讀取並提取單個公共證書,即.cer文件並將其存儲在密鑰庫中。 我不必擔心持久存在密鑰存儲區,因為已經有一個服務將.cer文件作為byte []接收並保存。

我想知道的是,我如何閱讀.p7b並提取單個.cer文件? 我知道可以通過openSSL命令完成,但我需要在java中做同樣的事情。 我還需要讀取Issued By名稱,因為它將用作持久保存證書的唯一鍵。

提前致謝

您可以使用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;
 }

請注意,PKCS#7可能包含多個證書。 大多數情況下,它包括在最終用戶證書和根CA之間構建證書鏈所需的中間證書頒發機構證書。

我成功地從p7b文件中讀取了各個.X509證書。 這是步驟

  • 第一步包括從java.io.File獲取byte []。 步驟包括從文件中刪除----- BEGIN PKCS7 -----和----- END PKCS7 -----,並解碼剩余的base64編碼的String。

     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()); 
  • 下一步是使用BouncyCastle api來解析文件

     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罐子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM