Is the salt format moot because the entropy of 32 binary bytes is the same as 42.7 base64 characters, or is one format really a better choice?
TLDR: moot, for the reason stated, as long as the whole thing is hashed and not otherwise used, and the hash used is secure, and the iterated hash construction on top of that is otherwise sound.
The fear that hashing constant bytes like =
, or hashing characters from a reduced set such that of Base64, or hashing more bytes, could cause a cryptographic issue like a loss of entropy or increased risk of collision, is unfounded as long as all the data enters a good hash like SHA-256, and is not otherwise used: the loss of entropy, if any, is computationally undetectable. If it was, it would allow to distinguish the hash from a random function¹. Even though SHA-1 and MD5 are broken, they are sill safe from such problem, thus we can be quite confident about this for the stronger SHA-256.
Introducing a binary-to-text transformation (e.g. Base64) as a pre-processigng of the salt:
- Slow downs the function, and that slow down benefits the attacker (which will perform the transformation only once in a password search attack). But for a well-parametrized function, that slowdown is negligible.
- Increases the length of the salt as effectively used (at least it should: again truncation would be bad). If the salt was repeatedly hashed in the iterated hash (wjich is possible but not usual), that may slow down the iterated hash sizably (especially if the transformation reaches a threshold requiring more compression rounds per iteration), both for the attacker and legitimate user, thus
- if the number of iterations is kept identical, the binary-to-text transformation will make the iterated hash slower, thus safer, but more costly for the legitimate user.
- if the number of iterations is adjusted for constant duration, then there will be less difference in security (and we can't tell in which direction)
There can be other side effects. For example, when the key input of HMAC-SHA-256 (a common building block in iterate hash function) exceeds 64 bytes, that key is replaced by its 32-byte SHA-256 hash, requiring at least two extra compression rounds. Thus adding one byte to the key input can abruptly increase duration (and reduce the entropy from up to 512 bit to less than 256, but it's not a worrying security issue).
Notice that since Colin Percival's Stronger Key Derivation via Sequential Memory-Hard Functions (presented at BSDCan 2009), a decent iterated password hashing function must use sizable RAM memory, and ideally be memory-hard (that is, massively parallel implementation should require that same sizable amount of memory for each instance running). It considerably raises the cost of a password search setup, because RAM is expensive, and thus make iterated password hashes sizably more secure. Nowadays, using constructions that require little RAM, like PBKDF2, is either incompetent, or a deliberate way to make the system breakable by well-funded attackers, who can use ASICs to outrun legitimate users by a very large factor.
¹ Modern hashes are expected to be undistinguishable from a random function. SHA-256 is believed to match this except for its length-extension property, and there's reason to believe that it is not an issue in the context.