2

Trying to generate a X509 with BouncyCastle api. Here is my piece of code.

    try {
        Security.addProvider(new BouncyCastleProvider()); // adding provider to
        String pathtoSave = "D://sureshtest.cer";

        KeyPair keyPair = generateKeypair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        X509Certificate trustCert = createCertificate(null,"CN=DigiCorp",
                "CN=Nextenders", publicKey, privateKey);
         // Create an input stream from the file containing the certificate.
        InputStream is =new FileInputStream(new File("D://validcertFormCa.pfx"));
        /*
         * CertificateFactory object is used for reading Certificates, CRL and
         * CertPaths. Create a factory object using the standard SPI pattern
         * used in JCA.
         */
        CertificateFactory factory =
                CertificateFactory.getInstance("X.509", "BC");

        /*
         * Generate a X509 Certificate initialized with the data read from the
         * input stream.
         */
        X509Certificate mastercert =
                (X509Certificate) factory.generateCertificate(is);
        java.security.cert.Certificate[] outChain = { trustCert,mastercert };
        trustCert.checkValidity();
        mastercert.checkValidity();
        KeyStore outStore = KeyStore.getInstance("PKCS12");
        outStore.load(null, null);
        outStore.setKeyEntry("my own certificate", privateKey,
                "admin123".toCharArray(), outChain);

        OutputStream outputStream = new FileOutputStream(pathtoSave);
        outStore.store(outputStream, "admin123".toCharArray());
        outputStream.flush();
        outputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

And run into the exception

    org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory$ExCertificateException
    at org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory.engineGenerateCertificate(Unknown Source)
    at java.security.cert.CertificateFactory.generateCertificate(Unknown Source)
    at com.nextenders.certificategeenrator.CertificateGenerator.testGenerateSignCertWithKeyStore(CertificateGenerator.java:119)
    at com.nextenders.facadeimplementation.facade.JUnitFacade.main(JUnitFacade.java:11)
Caused by: java.lang.IllegalArgumentException: unknown object in getInstance: org.bouncycastle.asn1.ASN1Integer
    at org.bouncycastle.asn1.ASN1Sequence.getInstance(Unknown Source)
    at org.bouncycastle.asn1.x509.TBSCertificate.getInstance(Unknown Source)
    at org.bouncycastle.asn1.x509.Certificate.<init>(Unknown Source)
    at org.bouncycastle.asn1.x509.Certificate.getInstance(Unknown Source)
    at org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory.readDERCertificate(Unknown Source)
    ... 4 more
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307

1 Answers1

2

What is mastercert supposed to be?

According to the docs for generateCertificate(), it expects that a "certificate provided in inStream must be DER-encoded and may be supplied in binary or printable (Base64) encoding". In other words, a DER or PEM encoded X509 certificate.

What you're providing it via that InputStream is a PFX file (a PKCS#12 file), not a DER or PEM encoded certificate.

My advice is to use openssl pkcs12 to extract the necessary certificate from the PKCS#12 file, and place it into a separate file, then change the code to load that instead of your PFX file.

mpontillo
  • 13,559
  • 7
  • 62
  • 90
  • I think I understand what you're trying to do now. Do you want to create a new certificate trusted by `mastercert`? If so, you'll need to extract the private key from that PFX file and then use it to sign a CSR signed with the *new* key. At least, that's how you'd do it conceptually. I don't know if there are shortcuts you can take with Java/Bouncy Castle. – mpontillo Jan 25 '14 at 08:11
  • See [this question](http://stackoverflow.com/questions/7230330/sign-csr-using-bouncy-castle) for details about how to sign the CSR. – mpontillo Jan 25 '14 at 08:18
  • Thanks mike for the valuable inputs. Will go through those. Recently entered in to encryption :) – Suresh Atta Jan 25 '14 at 09:55
  • @sᴜʀᴇsʜᴀᴛᴛᴀ, can you say more about the type of application this is? Typically you don't generate the private key for a leaf certificate on the CA itself. You want to keep the key secret, and confined to the client. There are protocols (such as SCEP) which will allow you to enroll a certificate over the network after generating a private key on the client. – mpontillo Jan 25 '14 at 09:58
  • My work flow is like. 1) An user applies for a digital certificate 2) An authorized user for example application owner approves that request . While approving he generates and grants one digital certificate using his own digital certificate which is authorized by CA. So later on, the applied user uses that certificate and encrypt and decrypt the data in our application. – Suresh Atta Jan 25 '14 at 10:02
  • 2
    @sᴜʀᴇsʜᴀᴛᴛᴀ, when the user applies for the digital certificate, she can generate the private key herself along with a CSR, and send that to the approver. Then the approver can just send the signed certificate, and doesn't have to worry about generating a key, getting the password to the PKCS#12 file to the requester, etc. The way you have the requestor generating the key, he can later impersonate the user if desired, since he has a copy of her private key. – mpontillo Jan 25 '14 at 18:53