0
$\begingroup$

Hash functions such as SHA-256 takes a binary string as input. Now given a hex string when we convert it to a normal text string the computed SHA-256 value would be the same. Herein lies my problem

Let us consider a simple string in hexadecimals 2E; its SHA-256 value is cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8.

When converted into byte form should we write 46 or 046. In either case the SHA-256 output is not matching:

For 46 you'd get 25fc0e7096fc653718202dc30b0c580b8ab87eac11a700cba03a7c021bc35b0c.

For 046 you'd get b2d084ae2bd0f4b38953ea3adb009b4f059816f93392addbcfb373399f183e88.

How do we convert from hexadecimals to a byte so the result is the same? What are the rules? As far as I know SHA-256 requires byte format.

I've used this (GitHub) software for calculating the SHA-256 values.

$\endgroup$
3
  • $\begingroup$ That site doesn't have a bytes option. How are you entering it as bytes? $\endgroup$ Commented Aug 17, 2021 at 20:25
  • $\begingroup$ there is a text option in drop down. I assume its bytes? $\endgroup$
    – J.Doe
    Commented Aug 17, 2021 at 20:26
  • 1
    $\begingroup$ The question is about SHA-256, not the different SHA (also known as SHA-0). SHA was a precursor of SHA-1. It turned out to be insecure, even more than SHA-1. The second (resp. third) hash shown is for the two-character (resp. three-character) sequence 46 (resp. 046) when encoded to as many bytes per ASCII or UTF-8, that is the bytes 0x34 0x36 (resp. 0x30 0x34 0x36) where the 0x prefix is for hexadecimal. $\endgroup$
    – fgrieu
    Commented Aug 17, 2021 at 20:37

2 Answers 2

7
$\begingroup$

Let us consider a simple string in Hex: 2E Its SHA value is:

cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8

Yes, that's correct.

When converted into byte form should we write 46 or 046.

Neither.

The whole idea of using hexadecimals for bytes is to represent the value of the bytes. So 2E is the hexadecimal representation of a single byte. You can also use other representations such as 00101110 in binary.

If you interpret it as ASCII text it would be the "dot" character. So printf "\x2E" | sha256sum is the same as printf "." | sha256sum on most systems. So on your site you could simply use a single dot as text. It's also possible to do this using echo but echo has too many portability issues to be considered a reliable alternative to printf.

Generally we don't represent bytes using decimals. If you do you'll probably have to program it specifically. For instance in Java you could use byte b = 46 or byte[] ba = { 46 } and then use that in a hash algorithm. If you really want to program it using command line then printf "\\x$(printf "%x" 46)" | sha256sum seems to work.

$\endgroup$
4
  • $\begingroup$ thank you. But when we initialize the data i.e. w[i]'s before running the Algorithm what do we do as the data required is in bytes by the variables (w[i]'s) being 32 bits)? Do we change the data to binary and then assign or we work directly on Hex by storing them in w[i]'s in hex format. I don't think latter would work and give the correct hash? $\endgroup$
    – J.Doe
    Commented Aug 17, 2021 at 20:42
  • $\begingroup$ I am trying to write SHA256 from scratch and this part is terribly confusing. The rest of the logic seems fine.. Lets assume the text in Hexa is: 2E 2F 05 EE that is to be populated in W[0]. How do we go about it and what would be its value ? $\endgroup$
    – J.Doe
    Commented Aug 17, 2021 at 20:44
  • 2
    $\begingroup$ Normally we create an interface using bytes for the SHA-256 hash function. In that case the value 2E 2F 05 EE in bytes would be converted to a single word 0x2E2F05EE when looking at the SHA-256 implementation. But please note that SHA-256 is defined as using big endian. You should never use hexadecimals created from a string, only bytes and words. Hexadecimals are only useful for debugging (the debugger can of course use them, and you can use them in debug print or trace statements), you should never use them for the implementation itself. $\endgroup$
    – Maarten Bodewes
    Commented Aug 17, 2021 at 20:51
  • $\begingroup$ You can just *shift the byte value into the right place, using << and then OR them together (beware of snags, lookup on StackOverflow on how to do this when you get stuck). Literals to define the initial values and constants can be defined using hexadecimal bytes or words are fine of course, e.g. h0 := 0x6a09e667 in the Wikipedia pseudo code is fine, 0x6a09e667 is not a string. $\endgroup$
    – Maarten Bodewes
    Commented Aug 17, 2021 at 20:56
0
$\begingroup$
  • List item

I used python to bring out the difference, when you take 2E and just encode as a byte and gives the byte encoded as b'2E'.

  • python has a method bytes.fromhex() for ex..
  • v=bytes.fromhex('474039')
  • here v is printed as b'G@9'
  • To decode use binascii.hexlify(v), and output will be b'474039' enter image description here
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.