# Encoding salt as hex before hashing bad practice?

I was reading a question about symmetric keys here and found the answer quite interesting. It mentions:

Be sure to pass in the raw bytes, and not, e.g., a hex-encoded string

Can someone elaborate on why this is bad? and also in the context of password hashing, is converting a salt to hex before sending it though the HMAC bad, and if so, why?

• The main theme here is that when you do encoding (of what kind ever, be it hex, base64), be sure to decoded before use and NOT use the ASCII byte representation of the encoding string. Cryptographic primitives are often optimized for specific lengths of keys or salts, so if you pass incorrect lengths, they often get hashed, which may increase the risk of collision Sep 14 '21 at 17:54

This does not talk about salt at all but about actual symmetric keys. Quoting the full paragraph:

Most programming environments provide some sort of "secure random" mechanism (a CSPRNG). You can use this to acquire a byte array of the appropriate length (e.g. 32 bytes for AES256), which can be used as a key. Be sure to pass in the raw bytes, and not, e.g., a hex-encoded string.

This means that if you're going to generate a 32 byte key (as shown in the paragraph), make sure these are 32 raw bytes and not 32 bytes of the hex encoded key.

The reason for this is simple:

• 32 raw bytes is 256^32 possible keys
• 32 bytes of hexadecimal data is 16^32 possible keys

If you need to pass the key around in hexadecimal representation, use the entire output which will be 64 bytes long.

As for salting, the strength of your salt depends on the size of it. It does not matter if it's raw or hexadecimal, it's the possible number of salts that matters.

• Strings may also be harder to destroy, they may even get "internalized", i.e. kept during the lifetime of the machine. Sep 13 '21 at 22:13
• Thanks for the great explanation! Sep 14 '21 at 12:27
• I don't understand how 32 raw bytes is different than 32 bytes. Based on your explanation, one hex character is stored in a byte, but that's not normal. There should be two hexadecimal digits per byte which would equate to 8 bits and a total of 256 possible values.
– Ben
Sep 14 '21 at 15:42
• Two hexadecimal digits can represent one byte. But if you have a string of this hexadecimal representation, a single byte of said string will be only one character. This is a common mistake people make: taking the first 32 bytes of a hexadecimal representation of raw data, not realizing they are dropping half of it.
– Marc
Sep 14 '21 at 15:50
• @marc great answer, however I agree that the description of 32 hex bytes is confusing: why not "32 characters (which needs 32 byte) of hexadecimal data is 16^32 possible keys" Sep 14 '21 at 17:53

Can someone elaborate on why this is bad?

Who said encoding salt before hashing was bad? When Tim McLean wrote:

Be sure to pass in the raw bytes, and not, e.g., a hex-encoded string.

he was specifically talking about generating a key for a symmetric cipher; he wasn't talking about generating an image to be hashed.

When you generate a salt for a hash, there is nothing wrong with using hex encoding.

• It is bad if it creates confusion about the data to be hashed. Cryptographic hashes operate on bytes, not characters, so text has to be encoded to bytes. Of course, unless you are using EBCDIC, there isn't likely to be any ambiguity when encoding hexadecimal digits. But if one implementation sees the text as hex-encoded bytes and decodes them, while another sees only the text and encodes it, they won't yield the same hash. Sep 15 '21 at 15:21