Question

I am trying to look for the class that implements the java.security.principal to provide Subject DN values for certificate. While searching, I came across X500Name is the class that is usually used for providing subject. However this doesn't implement the Principal interface. What suprises me is that the depreciated class of X500Name called X509Principal implements this interface unlike X500Name. What class to use?

Thanks

Was it helpful?

Solution

I recommend to use a bouncy castle class: org.bouncycastle.jce.X509Principal which implements java.security.Principal. In order to get org.bouncycastle.jce.X509Principal instance you can use the method:

public static org.bouncycastle.jce.X509Principal getSubjectX509Principal(
    java.security.cert.X509Certificate cert) throws CertificateEncodingException

of the class org.bouncycastle.jce.PrincipalUtil.

I give you a sample:

import java.io.FileInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

public class X509PrincipalSample {

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

            CertificateFactory cf = CertificateFactory.getInstance("X509");
            // certificate file must be encoded in DER binary format
            FileInputStream certificateFile = new FileInputStream("/tmp/cer.cer");
            X509Certificate certificate = (X509Certificate) cf.generateCertificate(certificateFile);
            X509Principal x509Principal = PrincipalUtil.getSubjectX509Principal(certificate);
            System.out.println(x509Principal.getName());
    }
}

Hope this helps,

EDIT:

As you said, org.bouncycastle.jce.X509Principal is deprecated in the last bouncy castle release. So you can use org.bouncycastle.asn1.x500.X500Name to work with subjectDN fields, however if you want to use a class that implements java.security.Principal use javax.security.auth.x500.X500Principal, I give you another example:

import java.io.FileInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import javax.security.auth.x500.X500Principal;

import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x500.style.IETFUtils;


public class X500NameSample {

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

         CertificateFactory cf = CertificateFactory.getInstance("X509");
         // certificate file must be encoded in DER binary format
         FileInputStream certificateFile = new FileInputStream("C:/Documents and Settings/aciffone/Escritorio/cer.cer");
         X509Certificate certificate = (X509Certificate) cf.generateCertificate(certificateFile);

         // using X500Principal
         X500Principal subjectX500Principal = certificate.getSubjectX500Principal();
         System.out.println(subjectX500Principal.getName());
         System.out.println(subjectX500Principal.getName(X500Principal.RFC1779));
         System.out.println(subjectX500Principal.getName(X500Principal.CANONICAL));

         // using X500Name
         X500Name x500name = new X500Name( subjectX500Principal.getName(X500Principal.RFC1779) );
         // you can get the different subject DN values with BCStyle constants
         RDN cn = x500name.getRDNs(BCStyle.CN)[0];
         System.out.println(IETFUtils.valueToString(cn.getFirst().getValue()));

         x500name = new X500Name( subjectX500Principal.getName() );
         // you can get the different subject DN values with BCStyle constants
         cn = x500name.getRDNs(BCStyle.CN)[0];
         System.out.println(IETFUtils.valueToString(cn.getFirst().getValue()));
    }
}

OTHER TIPS

Err, javax.security.auth.X500Principal?

All Implemented Interfaces:

    Serializable, Principal 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top