2

I'm trying to get serial number from a X.509 Cert.. When i compare the Serial number generated by my code with the actual serial number(on windows), leading zeroes of the actual serial number(of the X509 cert) are missing.

Any suggestions or alternative ways to get the serial number of the x.509 cert in hex with the leading zeroes??

Below is the code segment which I'm currently using:

InputStream in = new FileInputStream("cert");
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(in);
String serialNum = certificate.getSerialNumber().toString(16);
System.out.println(serialNum);
Janahan
  • 401
  • 8
  • 20
  • Why do you think there should be leafing zeroes? Can you show ASN-encoded serial number of the certificate? – Crypt32 Dec 08 '16 at 05:39
  • The actual serial number look likes ‎00 a6 XX XX XX XX XX XX XX. but serial number generated by above source code look likes a6 XX XX XX XX XX XX XX.. the leading 00 is missing. – Janahan Dec 08 '16 at 06:07
  • The serial number is defined as an ASN.1 INTEGER. Leading zeros are not significant. – user207421 Dec 08 '16 at 06:12
  • 4
    @EJP actually, leading zero is significant. ASN.1 integers are two-complement integers. As per RFC5280, serial number must be a positive integer. If the most significant bit of the positive integer is 1, then encoded value must be prepended with extra zero byte to indicate positive integer. – Crypt32 Dec 08 '16 at 06:21

2 Answers2

3

BigInteger has a toByteArray() method that re-adds the leading 00s:

byte[] serialNumBA = certificate.getSerialNumber().toByteArray()

Now you have several ways to convert the byte array to a hex string:

How to convert a byte array to a hex string in Java?

For example with Apache commons codec:

String serialNum = Hex.encodeHexString(serialNumBA);
Community
  • 1
  • 1
Omikron
  • 4,072
  • 1
  • 27
  • 28
  • 2
    Actually it doesn't _preserve_ 00s; it re-adds a single 00 iff needed for sign, which (fortunately) is the same rule ASN.1 DER uses. – dave_thompson_085 Dec 08 '16 at 20:17
  • Thank you..,when i read the serial number of self signed cert using openssl it's not showing the leading 00. but when i read the Serial number in windows it's showing the leading oo in the Serial number.May i know why? – Janahan Dec 09 '16 at 02:04
  • 2
    @jAnA When you have an integer value (a number) there are always several string representations of that value. You could also show a cert SN as a base 10 string representation. Omitting the leading zeroes isn't necessarily bad. If you only want to display the cert SN on screen, then it's probably fine, because it should be known that it has to be a positive number, which makes the 00s redundant. If you want to store the SN as a string in the database and later search for it, then you have to be really careful to always use the same algorithm for conversion. – Omikron Dec 10 '16 at 17:27
0
public static String getSerialNumFromCertificate (X509Certificate certificate) {
    String cert = certificate.toString();
    String serialNum ="";
    int fromIndex = cert.indexOf("SerialNumber:");
    int toIndex = cert.indexOf("Certificate Extensions:");
    for (int i = fromIndex + 15;i < toIndex; i++){
        if (Character.isLetterOrDigit(cert.charAt(i)))
            serialNum += cert.charAt(i);
    }
    return serialNum.trim();
}
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 29 '22 at 10:27