When I calculate in Java an SHA-256 of a string with the following method
public static void main(String[] args) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] hash = md.digest("password".getBytes()); StringBuffer sb = new StringBuffer(); for(byte b : hash) { sb.append(Integer.toHexString(b & 0xff)); } System.out.println(sb.toString()); }
I get :
5e884898da2847151d0e56f8dc6292773603dd6aabbdd62a11ef721d1542d8
on the commandline I do the following (I need the -n
to not add a newline) :
echo -n "password" | sha256sum
and get
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
if we compare these more closely I find 2 subtle differences
5e884898da2847151d0e56f8dc6292773603dd6aabbdd62a11ef721d1542d8 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
or :
5e884898da28 47151d0e56f8dc6292773603d d6aabbdd62a11ef721d1542d8 5e884898da28 0 47151d0e56f8dc6292773603d 0 d6aabbdd62a11ef721d1542d8
Which of the 2 is correct here?
Result: Both are but I was wrong...
fixed it by using :
StringBuffer sb = new StringBuffer(); for(byte b : hash) { sb.append(String.format("%02x", b)); }
Thanks!
Linux Mastery - Complete Linux Course SHA-256 in very simple terms is a cryptographic hash function that has a digest length of 256 bits. It is an algorithm on its own that is able to generate an almostunique and fixed size 256-bit(32-byte) hash.
Typically, on the internet, the SHA256 checksum is provided as a string directly in the main file or as a text file in the download section. Through the original checksum file, we can verify the checksum with the Checksum Utility tool.
Verifying SHA256 Checksum of a File in Linux To compare the checksum to the value in the file SHA256SUMS, run the command with the '-c' flag. This will take all the checksums in the file, compare them with the corresponding filename, and print the filename that matches the checksum.
Generate SHA-256 Hashes for Files We can use the sha256sum command in two modes; binary and text (the default). On Linux, both modes generate the same SHA-256 hash, and so the default mode is used throughout this tutorial.
I'll take a reasonable guess: both are outputting the same digest, but in your Java code that outputs the byte[]
result as a hex string, you outputting small byte values (less than 16) without a leading 0. So a byte with value "0x0d" is being written as "d" not "0d".
The culprit is the toHexString
. It appears to be outputting 6
for the value 6 whereas the sha256sum
one is outputting 06
. The Java docs for Integer.toHexString()
state:
This value is converted to a string of ASCII digits in hexadecimal (base 16) with no extra leading 0s.
The other zeros in the string aren't being affected since they're the second half of the bytes (e.g., 30
).
One way to fix it would be to change:
for(byte b : hash) { sb.append(Integer.toHexString(b & 0xff)); }
to:
for(byte b : hash) { if (b < 16) sb.append("0"); sb.append(Integer.toHexString(b & 0xff)); }
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