Java – What’s the Leaf Certificate and Sub Certificate used for and how to use them

cacertificatejavax509certificate

I have a problem when do business with AppleWallet.
They offer me three certificates:

  1. Leaf Certificate in String format;
  2. Sub Certificate in String format;
  3. Apple Root CA – G3 Cert file, ends with ".cer"

My problem: how do I verify and encode the data using RSA algorithm?

PS:The document makes clear that a PublicKey is provided by the Leaf Certificate. And the three certificate is in chain. Leaf Certificate is signed by Sub Certificate, and Sub Certificate is signed by AppleRootCA-G3.cer.

I need to do two things:

  1. Verify the three certificates.
  2. Extract the RSA PublicKey from the Leaf Certificate.

I have no idea how to do this.

Best Answer

What you basically have to do is construct a certificate chain if you didn't get it as a chain. A certificate chain basically consists of the end entity certificate (also, leaf certificate, the most important certificate in the chain) at the zeroth position and followed by the lesser important certificates. The CA Certificate being the least important.

So this is how the usual X.509 certificate chain looks like:

3. CA Certificate (self-signed)
    |
    |__ 2. Sub CA Certificate (signed by the above CA)
            |
            |__ 1. Sub-sub CA Certificate (if any) (signed by the above Sub CA)
                    |
                    |__ 0. End Entity Certificate (your certificate, signed by the above cert)

When you are constructing a certificate chain yourself from each certificate, you have, you have to see which certificate is signed by whom and then construct the chain in the above manner (the numbers in the tree indicate the index in the java's certificate array).

You can find which certificate is signed by whom by looking at the SubjectDN and IssuerDN. The Subject distinguished name is the end entity, and the Issuer distinguished name is the name of the entity who signed your certificate.

If you need to verify if a certificate is signed by another certificate programmatically, you could do this:

userCert.verify(caCert.getPublicKey());

You can extract a public key from a certificate using this code snippet:

CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
// Provided the certificate doesn't have certificate headers (---begin cert--- and ---end cert---)
Certificate cert = certificateFactory.generateCertificate(new FileInputStream(new File("CERTIFICATE_PATH")));

System.out.println(cert.getPublicKey());
Related Topic