3 ms·
Would a good drop in replacement here be something like hashing the two strings to the same length and using `hmac.compare_digest` ? https://docs.python.org/2/
by denom 12y ago
Would a good drop in replacement here be something like hashing the two strings to the same length and using `hmac.compare_digest` ?
https://docs.python.org/2/library/hmac.html#hmac.compare_digest https://docs.python.org/2/library/hmac.html#hmac.compare_dig...
Honestly, I don't know enough about timing attacks to be sure.
- mbreese 12y agoHere's some pseudo code... passed=true for (i=0; i< len(auth_username); i++) { if (i >= len(username) || auth_username[i] != username[i]) { passed = false } } for (i=0; i< len(auth_password); i++) { if (i >= len(password) || auth_password[i] != password[i]) { passed = false } } return passed This could potentially still be used to check the length of the username and password, but that would be more difficult. Hashing the username (like you mentioned) and comparing those character by character (like above) should yield the exact same timing for any inputs.
- TheLoneWolfling 12y agoNote: There is no guarantee that a compiler won't optimize this to non-constant time. And even if it keeps it constant time, a processor may end up running a function like this in non-constant time, due to caching and branch prediction effects.
- deleted 12y ago[deleted]
- zaroth 12y agoHashing the username (like you mentioned) and comparing those character by character (like above) should yield the exact same timing for any inputs. I like to use a "constant-time compare" against an HMAC of the inputs with a random key. You can initialize the key just once, it doesn't have to be a nonce, just an unknown value. The point is the attacker no longer knows or controls what value is on 'their side' of the comparison, so timing becomes irrelevant. For the comparison itself, I usually see |= and XOR being used and then the final value being checked to be non-zero, rather than a boolean. I think the theory is the compiler is a lot less likely the exit the loop early if you're accumulating with XOR versus a single branch flipping a boolean to be false. Here's a good write-up with some sample code: http://codahale.com/a-lesson-in-timing-attacks/ http://codahale.com/a-lesson-in-timing-attacks/. Note in that write-up they are talking about timing attacks comparing HMAC results, but that is when the attacker has control over the HMAC result not the HMAC input. If the attacker provided value is being fed into HMAC with a secret key, then you are absolutely safe from timing attacks. If the attacker has control over the HMAC result, and you are checking if that HMAC is valid, then you are back to defending against timing attacks by trying to achieve a constant-time compare. The only thing left to leak is the HMAC will clock differently based on the block-length of the input. But block size is rather coarse, and in this case you could limit inputs to be less than one block size in all cases.