fingerprint of a x.509 certificate

E

emrefan

While I realize perhaps comp.lang.java.security is a more appropriate
ng for my question, I think perhaps it isn't entirely inappropriate for
this one, so here I go. (I have posted on this in
comp.lang.java.security but it appeared that it wasn't so popular a ng
I thought it was afterall.)

My question is this: how to calculate the fingerprint of an x.509
certificate, programmatically in java, that is. I have already tried
this below but the result didn't look like what I
obtained otherwise (running "openssl x509 -noout -fingerprint -sha1 -in

<the cert file>"), so...

MessageDigest md = MessageDigest.getInstance( "SHA1" );
X509Certificate cert = X509Certificate.getInstance( new
FileInputStream( "somecert.crt" ) );
md.update( cert.getEncoded() );
byte[] fp = md.digest();

Please don't worry about not having the correct X509Certificate object
to do that digest operation on, because in the product code the same
object is obtained by another way and other operation on the cert
object had been successful.
 
B

Babu Kalakrishnan

emrefan said:
My question is this: how to calculate the fingerprint of an x.509
certificate, programmatically in java, that is. I have already tried
this below but the result didn't look like what I
obtained otherwise (running "openssl x509 -noout -fingerprint -sha1 -in

<the cert file>"), so...
MessageDigest md = MessageDigest.getInstance( "SHA1" );
X509Certificate cert = X509Certificate.getInstance( new
FileInputStream( "somecert.crt" ) );
md.update( cert.getEncoded() );
byte[] fp = md.digest();

In my experience the above method of obtaining the fingerprint works
fine, and does give results that match with openssl outputs. How are
you comparing the two ? Here's a utility routine that I use to dump the
fingerprint in a format that matches the output of openssl. Try using
this to dump the byte array "fp" and see if matches.

public static char[] HEX_CHARS =
{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
public static String dumpHex(byte[] data)
{
int n = data.length;
StringBuffer sb = new StringBuffer(n*3-1);
for (int i=0; i < n; i++)
{
if (i > 0) sb.append(':');
sb.append(HEX_CHARS[(data >> 4) & 0x0F]);
sb.append(HEX_CHARS[data & 0x0F]);
}
return sb.toString();
}

BK
 
A

Alex Artemiev

Try KeyStore object. I think, this is how "keytool" from Sun is done.
Babu Kalakrishnan said:
My question is this: how to calculate the fingerprint of an x.509
certificate, programmatically in java, that is. I have already tried
this below but the result didn't look like what I
obtained otherwise (running "openssl x509 -noout -fingerprint -sha1 -in

<the cert file>"), so...
MessageDigest md = MessageDigest.getInstance( "SHA1" );
X509Certificate cert = X509Certificate.getInstance( new
FileInputStream( "somecert.crt" ) );
md.update( cert.getEncoded() );
byte[] fp = md.digest();

In my experience the above method of obtaining the fingerprint works
fine, and does give results that match with openssl outputs. How are
you comparing the two ? Here's a utility routine that I use to dump the
fingerprint in a format that matches the output of openssl. Try using
this to dump the byte array "fp" and see if matches.

public static char[] HEX_CHARS =
{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
public static String dumpHex(byte[] data)
{
int n = data.length;
StringBuffer sb = new StringBuffer(n*3-1);
for (int i=0; i < n; i++)
{
if (i > 0) sb.append(':');
sb.append(HEX_CHARS[(data >> 4) & 0x0F]);
sb.append(HEX_CHARS[data & 0x0F]);
}
return sb.toString();
}

BK





----== Posted via Newsgroups.com - Usenet Access to over 100,000 Newsgroups ==----
Get Anonymous, Uncensored, Access to West and East Coast Server Farms at!
----== Highest Retention and Completion Rates! HTTP://WWW.NEWSGROUPS.COM ==----
 
E

emrefan

Babu said:
emrefan said:
My question is this: how to calculate the fingerprint of an x.509
certificate, programmatically in java, that is. I have already tried
this below but the result didn't look like what I
obtained otherwise (running "openssl x509 -noout -fingerprint -sha1 -in

<the cert file>"), so...
MessageDigest md = MessageDigest.getInstance( "SHA1" );
X509Certificate cert = X509Certificate.getInstance( new
FileInputStream( "somecert.crt" ) );
md.update( cert.getEncoded() );
byte[] fp = md.digest();

In my experience the above method of obtaining the fingerprint works
fine, and does give results that match with openssl outputs. How are
you comparing the two ? Here's a utility routine that I use to dump the
fingerprint in a format that matches the output of openssl. Try using
this to dump the byte array "fp" and see if matches.

public static char[] HEX_CHARS =
{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
public static String dumpHex(byte[] data)
{
int n = data.length;
StringBuffer sb = new StringBuffer(n*3-1);
for (int i=0; i < n; i++)
{
if (i > 0) sb.append(':');
sb.append(HEX_CHARS[(data >> 4) & 0x0F]);
sb.append(HEX_CHARS[data & 0x0F]);
}
return sb.toString();
}


Thanks for Babu for the answer! Yes indeed I had the correct
fingerprint but was misprinting it. How silly! I was using a
left-pad-string function (lPad()) written by a colleague without close
examination. <blush>

public static String bytesToHexString( byte[] paBytes ) {

StringBuffer sbRsltStr = new StringBuffer( paBytes.length * 3 );

for (int aryNdx=0; aryNdx < paBytes.length; aryNdx++) {
sbRsltStr.append(
Integer.toHexString( lPad( paBytes[ aryNdx ] & 0xFF, 2,
'0' ) ) );
}

return sbRsltStr.toString();
}

I think the way I called lPad() caused this definition of lPad() to be
matched:

public static String lPad( String str, int length, char padChr )

And the automatic conversion from int to String was quite beyond my
expectation.
 
E

emrefan

emrefan said:
Babu said:
emrefan said:
My question is this: how to calculate the fingerprint of an x.509
certificate, programmatically in java, that is. I have already tried
this below but the result didn't look like what I
obtained otherwise (running "openssl x509 -noout -fingerprint -sha1 -in

<the cert file>"), so...
MessageDigest md = MessageDigest.getInstance( "SHA1" );
X509Certificate cert = X509Certificate.getInstance( new
FileInputStream( "somecert.crt" ) );
md.update( cert.getEncoded() );
byte[] fp = md.digest();

In my experience the above method of obtaining the fingerprint works
fine, and does give results that match with openssl outputs. How are
you comparing the two ? Here's a utility routine that I use to dump the
fingerprint in a format that matches the output of openssl. Try using
this to dump the byte array "fp" and see if matches.

public static char[] HEX_CHARS =
{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
public static String dumpHex(byte[] data)
{
int n = data.length;
StringBuffer sb = new StringBuffer(n*3-1);
for (int i=0; i < n; i++)
{
if (i > 0) sb.append(':');
sb.append(HEX_CHARS[(data >> 4) & 0x0F]);
sb.append(HEX_CHARS[data & 0x0F]);
}
return sb.toString();
}


Thanks for Babu for the answer! Yes indeed I had the correct
fingerprint but was misprinting it. How silly! I was using a
left-pad-string function (lPad()) written by a colleague without close
examination. <blush>

public static String bytesToHexString( byte[] paBytes ) {

StringBuffer sbRsltStr = new StringBuffer( paBytes.length * 3 );

for (int aryNdx=0; aryNdx < paBytes.length; aryNdx++) {
sbRsltStr.append(
Integer.toHexString( lPad( paBytes[ aryNdx ] & 0xFF, 2,
'0' ) ) );
}

return sbRsltStr.toString();
}

I think the way I called lPad() caused this definition of lPad() to be
matched:

public static String lPad( String str, int length, char padChr )


Oops! Another mistake! It must be this below that I wrote (I corrected
the code and lost the bad version and I reconstructed it wrongly).

public static String bytesToHexString( byte[] paBytes ) {

StringBuffer sbRsltStr = new StringBuffer( paBytes.length * 3 );

for (int aryNdx=0; aryNdx < paBytes.length; aryNdx++) {
sbRsltStr.append(
lPad( Integer.toHexString( paBytes[ aryNdx ] & 0xFF ),
2, '0' ) );
}

return sbRsltStr.toString();
}


Anyway, I will have to restudy this thing carefully. Thanks for the
patience.
 
B

Babu Kalakrishnan

Anyway, I will have to restudy this thing carefully. Thanks for the
patience.

Well, it could also be that you used a "-sha" argument instead of
"-sha1" while running openssl. (and could therefore have been comparing
two different Hash values - SHA-0 vs. SHA-1), I got bitten by that one
once before (before I realized that typical openssl implementations
found on linux machines have SHA-0 compiled in, and the -sha option
gives the hash value using SHA-0 instead of the more common SHA-1 ) :)

BK
 
E

emrefan

Babu said:
Well, it could also be that you used a "-sha" argument instead of
"-sha1" while running openssl. (and could therefore have been comparing
two different Hash values - SHA-0 vs. SHA-1), I got bitten by that one
once before (before I realized that typical openssl implementations
found on linux machines have SHA-0 compiled in, and the -sha option
gives the hash value using SHA-0 instead of the more common SHA-1 ) :)

Nope, that was not the mistake. I had it correct and the fingerprint
was the same as what IE told me. All down to how I presented the
fingerprint in human readable form (well, sort of).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top