Bug in X509Certificate.GetSerialNumber and X509Certificate.GetSerialNumberString

  • Thread starter Thread starter John Allberg
  • Start date Start date
J

John Allberg

Hi!

There is a bug i X509Certificate.GetSerialNumber and
X509Certificate.GetSerialNumberString where the serialnumber bytes is in the
reverse order.

Example:
Open a verisign certificate. Verisign certificates have very long
serialnumbers, since they are generated from a hash value.

For my verisign certificate:
X509Certificate.GetSerialNumberString returns
FC67A62CBA193D0198061E48E65B8457

GetSerialNumber returns the same, even though it is in bytes.

When opening the certificate in explorer and looking at the serialnumber
field:
57 84 5b e6 48 1e 06 98 01 3d 19 ba 2c a6 67 fc

When parsing the certificate in an asn1 browser:
0 30 869: SEQUENCE {
4 30 718: SEQUENCE {
8 A0 3: [0] {
10 02 1: INTEGER 2
: }
13 02 16: INTEGER
: 57 84 5B E6 48 1E 06 98 01 3D 19 BA 2C A6 67 FC


When looking in Verisign admin tools, it is reported as
57845be6481e0698013d19ba2ca667fc

As you can see, this is the reverse of what X509Certificate.GetSerialNumber
reports. I'd say this is a bug.

Regards,

John Allberg
PS. This is a post using MSDN MSDN Managed Newsgroups with a registered MSDN
nospam mail account. It never worked for me before, but hey, sometime is
going to be the first, right? DS.
 
Hi

Based on my research, I think this is the different order about how win32
explorer and .NET framework handle the serial number byte array.
I have tried to open a test certificate and I find that the certificate's
byte array order is same as the output of .net's GetSerialNumber method. It
seems that the explorer has done the reverse job in advance. Based on my
knowlege, the serial number is used to identify the certificate which is
similar with GUID, so usually we use it to compare if two cert is identity.
So in the .net world, we do not need to do the reverse job.

While if you want to show the serialnumber same with the explorer.
We can just do the reserver job in .net as below.

// The path to the certificate.
string Certificate = @"c:\test.cer";
// Load the certificate into an X509Certificate object.
X509Certificate cert = X509Certificate.CreateFromCertFile(Certificate);
// Get the value.
byte[] results = cert.GetSerialNumber();
Array.Reverse(results);
// Display the value to the console.
foreach(byte b in results)
{
Console.Write("{0:x} ",b);
}
Console.WriteLine();

If you still have any concern, please feel free to post here.

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi

I am sorry if I make any confusion.
I use the hex editor e.g. UltraEditor to open the cer file and try to
observe the file and find that the serial number order is of the same of
.net one. While if I open the cer file in the explorer by doubleclick, the
order will be reverse. That is why I think the win32 approach have done
reverse.

Also I will help to try to forward your feedback.

Thanks for your understanding!

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi

Now I am contacting security support team, and I will give you an update
ASAP.

Thanks for you understanding!

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi

Based on my discussion with our support team, it seems that the behavior is
by design.
Here is the reply from senior escalation engineer.

X509Certificate.GetSerialNumber Method returns the serial number of the
X.509v3 certificate in "little endian" form.

====When using Crypto API===
CryptoAPI returns the serial number in the CERT_INFO structure. The serial
number is returned in little endian format rather than big endian format.

Here is what the documentation states:
SerialNumber
"BLOB containing the certificate's serial number. The least significant
byte is the zero byte of the pbData member of SerialNumber. The index for
the last byte of pbData. is one less than the value of the cbData member of
SerialNumber. The most significant byte is the last byte of pbData. Leading
0x00 or 0xFF bytes are removed. See CertCompareIntegerBlob."

It is normally up to the application using CryptoAPI to reverse the bytes
for display to match up with the standard CryptUI view (Explorer) or other
verisign tools.
====When using Crypto API===

X509Certificate.GetSerialNumber is returning the exact bytes returned by
CryptoAPI and is working as per the designed behavior.

It is up to the application to reverse the bytes to match up with other UI
tools.


If you still have any concern, please feel free to post here.

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top