# Keyless integrity checking with SHA-256

Currently a program is loading some files from an untrustworthy source (e.g. a CDN) which could have been tampered with. It has a known SHA-256 hash of the file stored locally, then it downloads the file from the CDN and compares the hash before loading the file into memory.

Because most of the SHA2 family suffers from length extension attacks (except for the truncated versions) this SHA-256 hash seems inadequate for integrity checking files coming from an untrustworthy source. A clever attacker could embed some extra data in the file being downloaded, the program would receive the file, calculate it to be the same SHA-256 hash, unwittingly execute that code and compromise the program.

The program's source code is publicly available, therefore embedding a secret key for HMAC is not an option and would be too slow anyway. SHA3 library code is not currently available either. However the SHA-384 hash is not vulnerable to the length extension attack. Would the next best option be to use SHA-384 for this integrity checking? It would also match up with NSA's recent recommendation to use at least SHA-384.

• Why don't you store the size as well as the hash? It's usually useful for other reasons (allocating sizes, detecting obvious transmission errors, etc.). – Gilles 'SO- stop being evil' Nov 19 '15 at 23:06
• SHA-384 is also my personal favorite, along with Blake. SHA-384 is also faster to compute on 64-bit processors – Richie Frame Nov 20 '15 at 0:45

A length extension attack doesn't let you find a collision. It lets you predict the hash for an input with an unknown component in the prefix. If you have $h = H(x)$ for unknown (or partially unknown) $x$, you can generate $h_y = H(x \vert\vert y)$ for arbitrary $y$ (this is not strictly correct; I've ignored padding, but for the purposes of this discussion it's a minor detail). However, you still can't find $z$ such that $h = H(x \vert\vert z) = H(x)$ faster than brute force.

• In this case $x$ is fully known to an attacker, it is a file on a public server. They can do H(x||y) with different combinations to try find a $y$ that will create the same $h$. Does an attacker need to do full brute force if $x$ is known? Maybe an attack to do this faster than brute force is not publicly known for SHA-256, but maybe there is an MD5 Flame level flaw which lets a nation state level attacker to find a collision much faster. In which case, why not use a hash function not vulnerable to length extension attack? – Hans Nov 20 '15 at 0:01
• The attack you suggest is a special-case of second preimage resistance: given $x$, it should be computationally infeasible to find a second preimage $x' != x$ such that $H(x) = H(x')$. In this case you're actually reducing the scope of the resistance to $x'$ of the form $x' = x\vert\vert y$. – Stephen Touset Nov 20 '15 at 0:12
• You're throwing the baby out with the bathwater; if you hypothesize state-level actors with arbitrary crypto-breaking capabilities, they can break any crypto. Keep in mind that creating and exploiting a chosen-prefix collision attack is considered more difficult than merely finding a collision (given a break in the underlying hash function). The answer to why not use a different hash function is because the described application doesn't require or benefit from resistance to length-extension attacks. You should choose primitives based on the capabilities actually required for your use-case. – Stephen Touset Nov 20 '15 at 0:15
• @Hans : $\;\;\;$ Because resistance to length extension attack is goal (which hash functions would have to go to a non-zero amount of effort to hopefully achieve) that is not at all relevant to your use case. $\:$ However, using randomized hashing would be good. $\;\;\;\;\;\;\;\;$ – user991 Nov 20 '15 at 4:28