Sunday 16 October 2016

Create PKCS#7/P7B Format in java program.

In this short article I will show you how to create pkcs7 format file to store certificate or chain of certificate.

A pkcs7 format  has a file extention of .p7b or .p7c. It can only contains certificates and chain certificates, not the private key.

I will use 3 certificates I have created in previous article and store them in pkcs7 format.

Code:
 import sun.security.pkcs.ContentInfo;  
 import sun.security.pkcs.PKCS7;  
 import sun.security.pkcs.SignerInfo;  
 import sun.security.x509.AlgorithmId;  
 import sun.security.x509.X509CertImpl;  
 import java.io.FileInputStream;  
 import java.io.FileOutputStream;  
 import java.io.IOException;  
 import java.security.cert.CertificateException;  
 import java.security.cert.X509Certificate;  
   
 public class App2 {  
   
   public static void main(String[] args) throws IOException, CertificateException {  
     //loading certificates stored as file  
     FileInputStream rootCAFile = new FileInputStream("D:\\rootCA.cer");  
     FileInputStream intermedCAFile = new FileInputStream("D:\\intermedCA.cer");  
     FileInputStream endUserCertFile = new FileInputStream("D:\\endUserCert.cer");  
   
     //create certificate objects from fileinputstream  
     X509Certificate rootCA = new X509CertImpl(rootCAFile);  
     X509Certificate intermedCA = new X509CertImpl(intermedCAFile);  
     X509Certificate endUserCert = new X509CertImpl(endUserCertFile);  
   
     //create the certificate hierarchy array  
     X509Certificate[] chain = new X509Certificate[3];  
     chain[0] = endUserCert;  
     chain[1] = intermedCA;  
     chain[2] = rootCA;  
   
     //create pkcs7 object with the cert chain created  
     PKCS7 pkcs7 = new PKCS7(new AlgorithmId[0], new ContentInfo(ContentInfo.DATA_OID, null),  
         chain, new SignerInfo[0]);  
   
     // store it as .p7b or .p7c format file  
     FileOutputStream fos = new FileOutputStream("D:\\bundle.p7b");  
     pkcs7.encodeSignedData(fos);  
     fos.close();  
   }  
 }  
   


As an outcome you will have below file in your file system.



Lets open the file and check out the content.



So you can see that it has packaged all the certificates we have provided in the cert chain.

That's it for now...
Stay tuned for my next article related to pkcs8 format....

Please post your comments and doubts!!!











6 comments:

  1. Thank you very much for the exemple.
    i have a probleme when i try it in eclipse 2019 with jre11.
    i always have that messsage "Error:(1, 20) java: package sun.security.pkcs is not visible
    (package sun.security.pkcs is declared in module java.base, which does not export it to the unnamed module)" can you help me please.
    Thank you

    ReplyDelete
    Replies
    1. starting from Java 9 the package sun.* is no longer available for external use. Please use different API/lib for that purpose.

      Delete
    2. https://www.oracle.com/technetwork/java/faq-sun-packages-142232.html

      Delete
    3. Thank you very much for your spontaneous response.
      plz know how we do the same thing for libraries like java security or bouncy castle. I search since but I do not find it.
      thank you so much...

      Delete
    4. I have used below bouncy castle lib and achieved the same:
      https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on/1.61


      import org.bouncycastle.jce.provider.BouncyCastleProvider;
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.security.NoSuchProviderException;
      import java.security.Security;
      import java.security.cert.*;
      import java.util.Arrays;
      import java.util.List;

      public class App2 {
      public static void main(String[] args) throws IOException, CertificateException, NoSuchProviderException {
      Security.addProvider(new BouncyCastleProvider());
      FileInputStream rootCAFile = new FileInputStream("E:\\rootCA.cer");
      FileInputStream intermedCAFile = new FileInputStream("E:\\intermedCA.cer");
      FileInputStream endUserCertFile = new FileInputStream("E:\\endUserCert.cer");
      CertificateFactory fact = CertificateFactory.getInstance("X.509","BC");
      // create the chain
      List chain = Arrays.asList(
      new Certificate[] {
      (X509Certificate)fact.generateCertificate(endUserCertFile),
      (X509Certificate)fact.generateCertificate(intermedCAFile),
      (X509Certificate)fact.generateCertificate(rootCAFile)
      });
      // create the CertPath
      CertPath path = fact.generateCertPath(chain);
      // write it out
      FileOutputStream fOut = new FileOutputStream("E:\\pkcs7.p7b");
      fOut.write(path.getEncoded("PKCS7"));
      fOut.close();
      }
      }

      Delete
    5. It works perfectly, thank too much for your assist.

      Delete