Leading zeros when computing SHA-256 hash

SoftwareStudent123 :

I am trying to compare the SHA-256 hash values of the same file with Python and Java. However, in some instances, the Python hash value has leading zeros, whereas the Java version does not. For instance, hashing somefile.txt in both programs yields:

Python: 000c3720cf1066fcde30876f498f060b0b3ad4e21abd473588f1f31f10fdd890

Java : c3720cf1066fcde30876f498f060b0b3ad4e21abd473588f1f31f10fdd890

Is it safe to simply remove leading 0's and compare or is there an implementation which does not produce the leading zeros?

Python Code

def sha256sum(filename):
    h  = hashlib.sha256()
    b  = bytearray(128*1024)
    mv = memoryview(b)
    with open(filename, 'rb', buffering=0) as f:
        for n in iter(lambda : f.readinto(mv), 0):
            h.update(mv[:n])
    return h.hexdigest()

print(sha256sum('/somepath/somefile.txt'))

# 000c3720cf1066fcde30876f498f060b0b3ad4e21abd473588f1f31f10fdd890

Java Code

public static String calculateSHA256(File updateFile) {
    MessageDigest digest;
    try {
        digest = MessageDigest.getInstance("SHA-256");
    } catch (NoSuchAlgorithmException e) {
        Log.e(TAG, "Exception while getting digest", e);
        return null;
    }

    InputStream is;
    try {
        is = new FileInputStream(updateFile);
    } catch (FileNotFoundException e) {
        Log.e(TAG, "Exception while getting FileInputStream", e);
        return null;
    }

    byte[] buffer = new byte[8192];
    int read;
    try {
        while ((read = is.read(buffer)) > 0) {
            digest.update(buffer, 0, read);
        }
        byte[] shaSum = digest.digest();
        BigInteger bigInt = new BigInteger(1, shaSum);
        String output = bigInt.toString(16);
        return output;
    } catch (IOException e) {
        throw new RuntimeException("Unable to process file for SHA256", e);
    } finally {
        try {
            is.close();
        } catch (IOException e) {
            Log.e(TAG, "Exception on closing SHA256 input stream", e);
        }
    }
}

Log.i("Output", calculateSHA256(somefile))

// I/Output: c3720cf1066fcde30876f498f060b0b3ad4e21abd473588f1f31f10fdd890
Karol Dowbecki :

The BigInteger conversion is ignoring leading zeros in your SHA-256 hash. Instead you should encode byte[] directly. As suggested in this answer you can use String.format():

StringBuilder sb = new StringBuilder();
for (byte b : shaSum) {
    sb.append(String.format("%02X", b));
}
return sb.toString();

When encoded as hex string the SHA-256 value has 64 characters, as per wiki example:

SHA256("")

0x e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=151634&siteId=1