3

i use EJBCA to generate a certificate from a CommonName. In java code i have generated private key and public key and then the csr for generate the certificate. Now i save the certificate in PEM format (.cer), but i need also private key so i want save with .pfx or p12 extension. How can i do? This is my actual code for generate certificate:

KeyPair keys;
    try {
        keys = KeyTools.genKeys("1024", AlgorithmConstants.KEYALGORITHM_RSA);   

        //SAVE PRIVKEY
        //PrivateKey privKey = keys.getPrivate();
        //byte[] privateKeyBytes = privKey.getEncoded();
        PKCS10CertificationRequest  pkcs10 = new PKCS10CertificationRequest("SHA256WithRSA",
                CertTools.stringToBcX509Name("CN=NOUSED"), keys.getPublic(), null, keys.getPrivate());
        //Print Privatekey
        //System.out.println(keys.getPrivate().toString());
        CertificateResponse certenv =  ws.certificateRequest(user1,
                                                               new String(Base64.encode(pkcs10.getEncoded())),
                                                                CertificateHelper.CERT_REQ_TYPE_PKCS10,
                                                                null,
                                                                CertificateHelper.RESPONSETYPE_CERTIFICATE);

        //Certificate certenv =  ejbcaraws.pkcs10Req("WSTESTUSER1","foo123",new 
        //String(Base64.encode(pkcs10.getEncoded())),null);

        return certenv.getCertificate (); 
    }catch (Exception e) {}

and with this i save the certificate:

File file = new File(path+"/"+ x509Cert.getSubjectDN().toString().replace("CN=", "") +".cer");

        FileOutputStream os = new FileOutputStream(file);  
        //os.write("-----BEGIN CERTIFICATE-----\n".getBytes("US-ASCII"));  
        //os.write(Base64.encode(x509Cert.getEncoded(), true));  
        //os.write("-----END CERTIFICATE-----".getBytes("US-ASCII"));  
        //os.close(); 

        PEMWriter pemWriter = new PEMWriter(new PrintWriter(os));
        pemWriter.writeObject(x509Cert);
        pemWriter.flush();
        pemWriter.close();
albciff
  • 18,112
  • 4
  • 64
  • 89
luca
  • 3,248
  • 10
  • 66
  • 145

1 Answers1

2

I never use EJBCA, however if you have the certificate and the private key and you want to create a PKCS12 you can use setKeyEntry(String alias,byte[] key,Certificate[] chain) method from java.security.KeyStore to add the entry, and then store(OutputStream stream, char[] password) method to save the PKCS12 on a file (look at API for more details). Your code could be something like:

import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;

public class SamplePKCS12 {

    public static void main(String args[]) throws Exception {

        String alias = // the alias for your key...
        PrivateKey key = // your private key
        Certificate[] chain = // an array with your EE certificate to your CA issuer
        // create keystore      
        KeyStore keystore = KeyStore.getInstance("PKCS12");
        // add your key and cert        
        keystore.setKeyEntry(alias, key.getEncoded(), chain);
        // save the keystore to file
        keystore.store(new FileOutputStream("/tmp/keystore.p12"), "yourPin".toCharArray());
    }
}

Note I suppose that you have your certificate and your private key as you said in your question. To work with PKCS12 you need SunJSSE provider (which is normally loaded by default), or alternatively you can use BouncyCastle provider.

Hope this helps,

albciff
  • 18,112
  • 4
  • 64
  • 89
  • I use a the KeyPair to generate a public/private keypair in the code, and created the certificate. Now, later on in a different request I wish to retrieve the p12 which was generated in a different request. In this situation how do I generate the p12 ? – sbose Feb 05 '16 at 11:14
  • @sbose This is a different question... if I understand well you want to load a PKCS12 from a previous created file isn't it? then you only have to use `keystore.load` method to load the file (using for example a `fileInputStream`). Basically something like: `KeyStore kstore= KeyStore.getInstance("PKCS12"); kstore.load(new FileInputStream("/somePath/yourP12File.p12"), "yourPassword".toCharArray()); ...` – albciff Feb 05 '16 at 11:50
  • Thanks for your response. No, create a pkcs12 from a previously generated certificate. The Certificate is present in the database in the CertificateData table. – sbose Feb 05 '16 at 11:56
  • @sbose If in your database you only store the certificate (not the `PKCS12`) then you can instantiate it using `CertificateFactory` (https://docs.oracle.com/javase/7/docs/api/java/security/cert/CertificateFactory.html) passing the byte you get from the database... If you need a more detailed response I think that it's better that you ask a new question providing all the details `:)`. – albciff Feb 05 '16 at 12:13
  • http://stackoverflow.com/questions/35223358/fetch-pre-generated-p12-certificate-from-ejbca Thanks a lot. I've tested out using CertificateFactory , but I used the private key from the KeyPair used to generated the certificate. However in this case, all I have is the Certificate object from the getCertificate call. – sbose Feb 05 '16 at 12:40