英文:
Java DigestUtils doesn't calculate SHA-256 correcly?
问题
以下是您要翻译的内容:
I have a file called test.sha256
, which contains:
5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
I have another file called data.txt
, which contains:
hello
I know that when using Files.readAllBytes(Path.of(data.txt));
the result is an array of signed
bytes. However what if I should do the following:
- Read
test.sha256
, which contains sha256 hash ofdata.txt
- Read
data.txt
and create sha256 hash from that file - Compare (1) and (2)
The problem is that when I use:
DigestUtils.getDigest("SHA-256").digest(Files.readAllBytes(data.txt))
The result differs from the content of test.sha256
file. And that is because Java cannot interpret unsigned
bytes using Files.readAllBytes
, but can do that using DigestUtils.getDigest().digest
.
Note though, that "SHA-256" is configurable, i.e., I don't hardcode it in real code (it is passed as an argument to the method).
My question is how I can compare hash "A" that has been read from a file and the hash that is generated from the data of file "B"? Where "A" is the actual hash of "B".
UPD: I confirm that they differ:
Arrays.equals(DigestUtils.sha256(Files.readAllBytes(data.txt)), Files.readAllBytes(test.sha256));
Java class being used: import org.apache.commons.codec.digest.DigestUtils
英文:
I have a file called test.sha256
, which contains:
5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
I have another file called data.txt
, which contains:
hello
I know that when using Files.readAllBytes(Path.of(data.txt));
the result is an array of signed
bytes. However what if I should do following:
- Read
test.sha256
, which contains sha256 hash ofdata.txt
- Read
data.txt
and create sha256 hash from that file - Compare (1) and (2)
Problem is that when I use:
DigestUtils.getDigest("SHA-256").digest(Files.readAllBytes(data.txt))
Result differs from the content of test.sha256
file. And that is because Java cannot iterpret unsigned
bytes using Files.readAllBytes
, but can do that using DigestUtils.getDigest().digest
.
Note though, that "SHA-256" is configurable, i.e I don't hardcode it in real code (it is passed as an argument to the method).
My question is how I can compare hash "A" that has been red from a file and the hash that is generated from a data of file "B" ? Where "A" is the actual hash of "B".
UPD: I confirm that they differ:
Arrays.equals(DigestUtils.sha256(Files.readAllBytes(data.txt)), Files.readAllBytes(test.sha256));
Java class being used: import org.apache.commons.codec.digest.DigestUtils
答案1
得分: 4
问题出在DigestUtils.getDigest("SHA-256").digest(..)
的输出是摘要的原始字节的字节数组,而你的test.sha256
文件包含的是十六进制编码的值。
为解决这个问题,你需要将原始字节编码为十六进制,例如使用Java 17中引入的HexFormat
,或使用DigestUtil.sha256Hex(..)
方法,该方法将执行摘要然后生成一个十六进制编码的字符串。
例如:
System.out.println(DigestUtils.sha256Hex(Files.readAllBytes(data)));
和
Objects.equals(
DigestUtils.sha256Hex(Files.readAllBytes(data)),
Files.readString(test.sha256));
或者,如果你想保持哈希参数化,而不能使用Java 17的HexFormat
:
Hex.encodeHexString(
DigestUtils.getDigest("SHA-256")
.digest(Files.readAllBytes(data)));
其中Hex
是org.apache.commons.codec.binary.Hex
。
英文:
The problem you have is that the output of DigestUtils.getDigest("SHA-256").digest(..)
is a byte array of the raw bytes of the digest, while your test.sha256
file contains a hex encoded value.
To address this problem, you'll need to encode the raw bytes to hex, for example using HexFormat
(introduced in Java 17), or the DigestUtil.sha256Hex(..)
method which will perform the digest and then produce a hex-encoded string.
For example:
System.out.println(DigestUtils.sha256Hex(Files.readAllBytes(data)));
and
Objects.equals(
DigestUtils.sha256Hex(Files.readAllBytes(data)),
Files.readString(test.sha256));
Or, if you want to keep the hash parameterized and you cannot use HexFormat
of Java 17:
Hex.encodeHexString(
DigestUtils.getDigest("SHA-256")
.digest(Files.readAllBytes(data)));
where Hex
is org.apache.commons.codec.binary.Hex
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论