4
$\begingroup$

A way to prevent timing attacks for hash string comparison is to perform additional HMAC signing in order to randomize the verification process (see Double HMAC Verification).

In addition to the second HMAC hashing for each hash, a random salt of random length is added to both in order to make the hashing timing / process even less predictable.

My PHP implementation of this look like this:

function hmac_verify ($hash_original, $message, $key) {

    $hmac_salt = '...'; // was added at the original HMAC signing
    $random_salt = openssl_random_pseudo_bytes (rand(16,96));

    $raw_hash = hash_hmac('sha512', $message . $hmac_salt, $key, true);
    $hash_compare = base64_encode ($raw_hash); // $hash_original is in base64 
    $hash_compare_safe = hash_hmac('sha512', $hash_compare, $random_salt, true);
    $hash_original_safe = hash_hmac('sha512', $hash_original, $random_salt, true);

    if ($hash_compare_safe === $hash_original_safe) return true;
        else return false;

}

The function is called in this way after decrypting the encrypted text in order to verify the decryption result:

if (!hmac_verify ($hmac_hash, $plaintext . $cipher_text, $key . $iv)) return "HASH ERROR";

Will this successfully prevent a timing attack? Am I doing anything unnecessary? Could something be improved?

$\endgroup$
5
$\begingroup$

Will this successfully prevent a timing attack?

Strictly speaking you should be checking if openssl_random_pseudo_bytes happens to be returning cryptographically strong numbers or not. If not, an attacker could guess be able to launch a timing attack practically as easily as without the extra HMAC.

(Got to love PHP... Even the function name: random "pseudo bytes"...)

You should also, if possible, HMAC the raw output rather than the base64. The base64 encoding function might itself even allow timing attacks (probably not but who knows), so you would be better off using the raw values. It is also faster.

Am I doing anything unnecessary? Could something be improved?

The $random_salt is actually a key, so you should call it and treat it as such. You could reuse it across function calls, if you are after performance.

There is no advantage to generating a random-length key. You should be using a key size that matches the overall security strength you are aiming for, but e.g. 256 bits would be plenty.

The security of this relies on the security of HMAC. As long as the key is secret, no one will be able to learn anything about the original hash even if the final comparison leaked the value. And if the key is long enough it cannot be brute forced. Randomness does not help beyond generating a secure key.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks. Openssl_random_pseudo_bytes is cryptographically strong (see e.g. security.stackexchange.com/questions/26206/…). Can you explain why using a key of random length has no advantage over a fixed-length key, since it adds to the randomness of the string comparison? $\endgroup$ – azren Oct 25 '15 at 22:04
  • $\begingroup$ @azenz, behind that link they use the same "strictly speaking" wording (by chance, I hadn't seen that before). I added some justification for why random length key won't help. $\endgroup$ – otus Oct 26 '15 at 5:18
  • $\begingroup$ "The $random_salt is actually a key, so you should call it and treat it as such. You could reuse it across function calls, if you are after performance." I disagree; it should be treated a nonce so as to guarantee that the timing side-channel is blinded. $\endgroup$ – Scott Arciszewski Oct 26 '15 at 8:04
  • $\begingroup$ @ScottArciszewski, nonces are not secret. If you assume the adversary knows $random_salt they can brute force the HMAC just as if there was no blinding. On the other hand, reuse of the value does not lead to any attacks (that I can tell – correct me if I'm wrong of course). $\endgroup$ – otus Oct 26 '15 at 8:49
  • 1
    $\begingroup$ @ScottArciszewski the comments aren't really the place to discuss this. Maybe one of us should ask a new question about this? $\endgroup$ – otus Oct 26 '15 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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