For a hash function what is the best secure method, XOR or Concatenate:
h(data1 XOR data2 XOR data3 XOR data4) ? or use h(data1||data2||data3||data4)?
Information Security Stack Exchange is a question and answer site for information security professionals. It only takes a minute to sign up.Sign up to join this community
It really depends on what you are trying to do; a hash function is a tool. Just like a hammer is good if you want to hit on nails, not so much if you want to feed a baby (a baby bottle is better for that).
One main usage of hash functions is to get a "digest" which represents a given piece of data. This is the first step for digital signatures: instead of signing a piece of data, we actually sign the hash of the piece of data; the hash is "as good" as the original data for verification purposes (since you cannot cheat a hash function) but the hash value has a fixed, short size which is much more convenient to map into the mathematical structures used by the signature algorithm. A similar usage of hash functions is for storing "verification tokens" such as what happens with passwords: you store the hash of the password, so that when the password "comes back", you can verify that it matches what you stored; but what you store is not sufficient to (easily) recompute the password.
Apparently, you want to hash a set of data elements: the input data is a set of four data blocks.
If your set is ordered (you consider "data1,data2,data3,data4" to be distinct from "data1,data2,data4,data3") then you should use concatenation, not the XOR. For that matter, you would probably want to hash a somewhat less ambiguous encoding, because if data1 is "df" and data2 is "gh", then concatenation yields "dfgh" which is the same value that you would get from concatenating "d" with "fgh". If your data elements are string of characters which never include a comma, then you can concatenate them with comma signs as separator, which is enough to avoid this ambiguity.
If your set is unordered (you consider "data1,data2,data3,data4" to have the same meaning as "data1,data2,data4,data3", and you want both to hash to the same value), then the XOR is not the right solution either; you should instead enforce a "sorting step" in which the four data elements are first ordered unambiguously (e.g. lexicographic order), and then you do concatenation as above.
I don't imagine a scenario where XORing would do something useful here, but maybe you have a use case where the XOR happens to do the right thing. It really depends on what you want to achieve.
In your example, XOR is a way of scrambling the data. Hash functions already provide good scrambling so concatenating would provide a longer piece of data that would better resist a brute-force attack.
If you use XOR and the attacker can control the
data1 field, then the attacker can control the output of the XOR operation and the resulting hash. An example would be XOR-ing something controlled by the attacker with a something that is changing, like a time-stamp. The attacker can craft an input in order control the output of the XOR, therefore eliminating the effect of the changing time-stamp.
Concatenation*: It will give you:
A longer keyspace. Even if data1-4 never collide when XORed, the input keyspace is larger, and will be harder to brute force its way into.