0

I have this code created using Google Guava:

String sha256hex = Hashing.sha256()
                    .hashString(cardNum, StandardCharsets.UTF_8)
                    .toString();

How I can verify the generated values is a properly generated hash?

Peter Penzov
  • 1,126
  • 134
  • 430
  • 808
  • 2
    It's unclear what you're trying to achieve here. Do you mean you want to check that your code works? Or that the hash matches some known hash elsewhere? Please edit your question to provide more information. – Jon Skeet Jun 02 '22 at 11:37
  • I want to verify that the generated hash is a valid hash. For example hash length is correct and the algorithm used to generated the hash is sha256. – Peter Penzov Jun 02 '22 at 11:45
  • You could do that with unit tests - hash some strings for which you already know the hash, and check the result against that known hash. – Jon Skeet Jun 02 '22 at 13:07
  • I agree but in my application I need to check already created strings are they hashed. – Peter Penzov Jun 02 '22 at 13:18
  • 1
    I really don't understand what you're asking. Yes, they're hashed, because you've just called `hashString` - why would they *not* be hashed? What are you expecting to go wrong? To put it another way: if you were asking the same question about "adding two integers" instead of hashing, what would you expect an answer to look like? – Jon Skeet Jun 02 '22 at 13:21
  • For sha256 you could check the length (only for correct length checking) since it should be 256 bits long. When using hex representation 4 bits encode a character so I guess you could check if the length is 256/4 = 64. Should you yourself check this? I don't think so. – void void Jun 04 '22 at 13:18
  • It is save to assume that `String sha256hex` is a properly generated hash; so what's the question? – Martin Zeitler Jun 04 '22 at 13:24
  • I receive from a Rest API call hash value. How I can verify it that this value is a valid hash? – Peter Penzov Jun 04 '22 at 13:25
  • Well, you probably might want to validate if it's a correct HMAC-SHA256 signature; but this always requires an additional string, which is the same one which had been used for signing it. This would be about [PHP](https://stackoverflow.com/questions/70689467/how-to-validate-a-huawei-x-hw-signature), but should provide an idea of what I'm talking about. – Martin Zeitler Jun 04 '22 at 13:26
  • Any idea how I can do this with Java? – Peter Penzov Jun 04 '22 at 13:31
  • Does this answer your question? [HMAC-SHA256 Algorithm for signature calculation](https://stackoverflow.com/questions/7124735/hmac-sha256-algorithm-for-signature-calculation) – Martin Zeitler Jun 04 '22 at 13:33
  • @MartinZeitler *"you probably might want to validate if it's a correct HMAC-SHA256 signature"* Why would a REST API return a HMAC-SHA256 signature? – Olivier Jun 05 '22 at 07:46
  • @Olivier Nope, a REST API commonly would receive such header values ...in order to determine if a post-back originated from where one thinks it originated from. There's no login being performed, but one still can assume the identify like that. It's quite common (while it also works without validating the signature). – Martin Zeitler Jun 05 '22 at 12:51

2 Answers2

2

SHA-256 and, in general, the family of SHA 2 algorithms is wonderfully described in Wikipedia and different RFCs, RFC 6234 and the superseded RFC 4634.

All these sources dictate that the output provided by the SHA 256 hash function is 256 bits length, 32 bytes (the number that accompanies the SHA word is the mentioned value for every algorithm in the family, roughly speaking).

These sequence of bytes is typically encoded in hex. This is the implementation provided by Guava as well.

Then, the problem can be reduced to identify if a string in Java is a valid hex encoding.

That problem has been already answered here, in SO, for example in this question.

For its simplicity, consider the solution proposed by @laycat:

boolean isHex = mac_addr.matches("^[0-9a-fA-F]+$");

As every byte is encoded with two hex characters and, as mentioned, the SHA-256 algorithm produces and output of 32 bytes you can safely check for a string of 64 characters length, as suggested in the answer of @D.O. as well. Your validation code could be similar to this:

boolean canBeSha256Output = sha256Hex.matches("^[0-9a-fA-F]{64}$");

Please, be aware that there is no possibility for saying if a character hex string of a certain length on its own is or not the result of a hash function, whichever hash function you consider.

You only can be sure that a hash output is a hash output if and only if it matches the result of applying the corresponding hash function over the original input.

jccampanero
  • 50,989
  • 3
  • 20
  • 49
1

You could use a regex to verify that it looks like a sha256 hash(64 hexadecimal characters), like

\b[A-Fa-f0-9]{64}\b
D. O.
  • 109
  • 2
  • 9