I'm trying to implement an X.509 certificate generator from scratch (I know about the existing ones, but I need yet another one). What I cannot understand is how to calculate the SHA-1 (or any other) fingerprint of the certificate.
The RFC5280 says that the input to the signature function is the DER-encoded tbsCertificate field. Unfortunately, the hash that I calculate differs from the one produced by OpenSSL. Here's a step-by-step example.
openssl x509 -fingerprint
dd
(or anything else) and store it in a separate file; calculate its hash using the sha1sum
utilityNow, the hashes I get at steps 2 and 3 are different. Can someone please give me a hint what I may be doing wrong?
Double-click the certificate. In the Certificate dialog box, click the Details tab. Scroll through the list of fields and click Thumbprint. Copy the hexadecimal characters from the box.
A certificate thumbprint is an hexadecimal string that uniquely identifies a certificate. A thumbprint is calculated from the content of the certificate using a thumbprint algorithm. CES accepts Secure Hash Algorithm 1 (SHA-1) thumbprints in the 40-digit hexadecimal string form without spaces.
Open a terminal and run the keytool utility provided with Java to get the SHA-1 fingerprint of the certificate. You should get both the release and debug certificate fingerprints. Note: When using Play App Signing, the upload key certificate will be different than the app signing key certificate.
509 specification. The Certificate Fingerprint is a digest (hash function) of a certificate in x509 binary format. It can be calculated by different algorithms, such as SHA1 for Microsoft Internet Explorer.
Ok, so it turned out that the fingerprint calculated by OpenSSL is simply a hash over the whole certificate (in its DER binary encoding, not the ASCII PEM one!), not only the TBS part, as I thought.
For anyone who cares about calculating certificate's digest, it is done in a different way: the hash is calculated over the DER-encoded (again, not the PEM string) TBS part only, including its ASN.1 header (the ID 0x30 == ASN1_SEQUENCE | ASN1_CONSTRUCTED and the length field). Please note that the certificate's ASN.1 header is not taken into account.
The finger print is similar to term "Thumbprint" in .net. Below code snippet should help you to compute finger print :
public String generateFingerPrint(X509Certificate cert) throws CertificateEncodingException,NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
byte[] hash = digest.digest(cert.getEncoded[]);
final char delimiter = ':';
// Calculate the number of characters in our fingerprint
// ('# of bytes' * 2) chars + ('# of bytes' - 1) chars for delimiters
final int len = hash.length * 2 + hash.length - 1;
// Typically SHA-1 algorithm produces 20 bytes, i.e. len should be 59
StringBuilder fingerprint = new StringBuilder(len);
for (int i = 0; i < hash.length; i++) {
// Step 1: unsigned byte
hash[i] &= 0xff;
// Steps 2 & 3: byte to hex in two chars
// Lower cased 'x' at '%02x' enforces lower cased char for hex value!
fingerprint.append(String.format("%02x", hash[i]));
// Step 4: put delimiter
if (i < hash.length - 1) {
fingerprint.append(delimiter);
}
}
return fingerprint.toString();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With