how to compare distinct implementations of java.security.cert.X509Certificate
I'm using bouncycastle org.bouncycastle.jce.provider.X509CertificateObject and sun.security.x509.X509CertImpl in different parts of my app, and sometimes I need to compare them for equality, equals() method is not working and methods like getSubjectDN().getName() display different results for each of these implementations, ho开发者_StackOverfloww could I compare these certificates for equality without going to binary DER or PEM comparison?
A safe way to tell if two certificates are equal is to compare their binary representation. Both the Bouncy Castle and Sun's implementation feature a getEncoded
method. You could compare the two with Arrays#equals.
You should avoid comparing SubjectDN or IssuerDN strings, it is quite possible that the representation differs even if on the binary level they are perfectly equal. I had to learn this the hard way when interfacing with .NET - the naming of the individual relative distinguished names (such as CN, O, OU...) was different for more exotic RDNs. My advice would be to stay on the binary level for comparison, tricky high-level comparisons are error-prone and harder to maintain.
Another way would be to compare using MD5 or SHA-1 hashes of the certificate data. This is how the certificate fingerprint is generated, and would give you assurances of the equality of the two.
You can try to convert the certificate in this case client (BouncyCastle) to java.security
try {
byte[] encoded = client.getEncoded();
ByteArrayInputStream bis = new ByteArrayInputStream(encoded);
java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance("X.509");
x509CertificateC = (java.security.cert.X509Certificate) cf.generateCertificate(bis);
} catch (java.security.cert.CertificateEncodingException e) {
} catch (java.security.cert.CertificateException e) {
}
精彩评论