Got "data isn't an object ID (tag = 49)" while generating X509 cert

Kaninchen picture Kaninchen · Jan 6, 2017 · Viewed 14.3k times · Source

I'm trying to generate my own CSR for my keystore, but it didn't go well and that error is confusing me. Here is my code:

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;

public class CreateKeyTest {

    public static void main(String[] args) throws OperatorCreationException, IOException, GeneralSecurityException {
    KeyPairGenerator kpg;
    KeyPair kp;
    RSAPublicKey pubKey;
    RSAPrivateKey privKey;

    FileOutputStream out;
    KeyStore ks;
    FileInputStream in;
    FileInputStream bFis;

    try {
        ks = KeyStore.getInstance("JKS");

        kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        kp = kpg.generateKeyPair();
        pubKey = (RSAPublicKey) kp.getPublic();
        privKey = (RSAPrivateKey) kp.getPrivate();

        // generate CSR
        ContentSigner sign = new JcaContentSignerBuilder("SHA1withRSA").build(privKey);

        X500NameBuilder nBuilder = new X500NameBuilder();
        nBuilder.addRDN(BCStyle.CN, "TestCSR");
        nBuilder.addRDN(BCStyle.C, "ER");
        nBuilder.addRDN(BCStyle.E, "[email protected]");
        X500Name name = nBuilder.build();

        PKCS10CertificationRequestBuilder cerReq = new JcaPKCS10CertificationRequestBuilder(name, pubKey);
        PKCS10CertificationRequest request = cerReq.build(sign);

        PEMWriter pWr = new PEMWriter(new FileWriter(new File("D:\\test.csr")));
        pWr.writeObject(request);
        pWr.flush();
        pWr.close();

        bFis = new FileInputStream("D:\\test.csr");
        BufferedInputStream ksbufin = new BufferedInputStream(bFis);
        X509Certificate certificate = (X509Certificate) CertificateFactory.getInstance("X.509")
                .generateCertificate(ksbufin);

        ks.setKeyEntry("RSA_key", kp.getPrivate(), "changeit".toCharArray(),
                new java.security.cert.Certificate[] { certificate });

        out = new FileOutputStream("key.store");
        ks.store(out, "changeit".toCharArray());

        System.out.println("New Keystore Generated");
        out.close();
    } catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException
            | OperatorCreationException e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}
}

When I execute it, it showed me the exception:X509.ObjectIdentifier() -- data isn't an object ID (tag = 49), and it could be back-traced to generateCertificate(ksbufin). But I checked test.cer and it do have certificate data in there, and that exception message confused me, don't even know what does that mean(object ID? tag = 49? I didn't see I generated an ID in my code.).

Can anyone help me out this mud?

Answer

pedrofb picture pedrofb · Jan 6, 2017

The error message is correct, test.csr does not contain a certificate. You have built it using a PKCS10CertificationRequest, so it consenquently contains a Certificate Signing Request (CSR).

You have generated a key pair, private and public, and a CSR. The CSR is a request of a certificate to a Certification Authority (CA). It contains the public key and some expected attributes for the certificate (CN, C, OU, etc). CSR is signed with the private key and has to be sent to CA. The CA will extract the public key, generates a certificate and signs it. See Certificate enrollment process

If you want a Certificate, you need to get signed the certificate by the CA