in my app I'm using the sha256 of the issuer Name (x509CertImpl.getIssuerDN().getName()) and the certificate serial number to uniquely identify a certificate, but now I have realized that other implementations of X509Name as the implementation of Bouncy Castle library displays something different when I call bcX509Name.getName() so this identifier doesn't work for me... my question is how could I get an unique identifier for an X509Name... maybe an ASN.1 or DER encoded representation of both will be the same.
2 Answers
It is not clear from the question whether you are using a java.security.cert.X509Certificate
, or some Bouncy Castle class that doesn't use the JCA interfaces.
In any case, there should be a method that returns an object that represents the issuer's X.500 name. This object should have a method that returns the ASN.1 encoding of the name as a byte array. Use this as a component of your key.
If you are using the standard X509Certificate
or Bouncy Castle's X509CertificateObject
, use something like this (and if you aren't using one of these classes, please be more specific):
X509Certificate x = ...;
byte[] issuer = x.getIssuerX500Principal().getEncoded();

- 265,237
- 58
- 395
- 493
-
I'm using both, Java and BC classes. X509CertificateObject.getSubjectDN() (CA I want an unique id for) and X509CertImpl.getIssuerDN() (issued cert from which I want to point to the CA) By the way, the returns for these object haven't a getEncoded() method. – Jaime Hablutzel Jul 25 '11 at 16:32
-
@jaime - They don't have `getEncoded()` because you are using the *wrong method.* Use `getIssuerX500Principal()`. The `getXxxDN()` methods that return a `Principal` are deprecated and should not be used for anything. Also, you should use the interfaces from the core API (`X509Certificate`), not the private implementation classes (`X509CertImpl`), which are subject to change. – erickson Jul 25 '11 at 16:41
-
So you suggest that I should do something like this: x509Impl.getIssuerX500Principal().getEncoded() and x509CertificateObject.getSubjectX500Principal().getEncoded() and those byte arrays should be the same? (x509Impl has been issued by x509CertificateObject). One more thing... these getEncoded() methods are incrementing its value with each call... is that a expected behaviour? – Jaime Hablutzel Jul 25 '11 at 17:02
-
Yes, those should be the same, and no, the values returned by `getEncoded()` will not change between calls. – erickson Jul 25 '11 at 17:14
-
1This worked: byte[] zas = x509CertificateObject.getSubjectX500Principal().getEncoded(); byte[] foo = x509Certificate.getIssuerX500Principal().getEncoded(); Arrays.equals(zas, foo) – Jaime Hablutzel Jul 25 '11 at 17:24
-
@jaime - Great! That's exactly what I was shooting for. – erickson Jul 25 '11 at 17:32
IssuerDN is a complex structure and different libraries might have different mechanisms of "serializing" it to string. So you might need to re-think your approach. In general it's ok to use hash of the certificate itself (in whole) + serial number comparison (to bring possibility of collision to almost 0).

- 45,135
- 8
- 71
- 121
-
You say, the hash of the CA and the serial number of the issued cert? It sounds practical – Jaime Hablutzel Jul 25 '11 at 16:36
-
@jaime hash the certificate "body" - serialized DER format. It's a standard and uniform procedure for all libraries. – Eugene Mayevski 'Callback Jul 25 '11 at 20:36