# Case insensitive verification of HMAC / Base64 signature

I am signing a short message using the base64 of an HMAC, like this (python):

import hashlib
import hmac
import base64

raw = hmac.new("key", msg="secret", digestmod=hashlib.sha1).digest()
base64.urlsafe_b64encode(raw)


That last line returns 'ux5F7Ye-rpwvysbzUBLu-wGaYXA=', which I use as the signature. To verify a signature we sign the data again, and compare with the user provided signature.

(The real implementation is Django's Cryptographic signing, the heart being salted_hmac. I'm simplifying a little for the question.)

How risky would it be to do the comparison case insensitive? e.g. the signature above would also allow 'ux5f7ye-rpwvysbzublu-wgayxa=' and many others.

Motivation is I am using the signature in an email address, which is case insensitive, which as you can imagine doesn't work. I can change to a different encoding (suggestions?), but that would require everyone updating the email addresses they use. I'm asking this question to see whether I can safely avoid making everyone do that.

-
Actually, whether an email address is treated as case-sensitive or not depends on the Mail server. There is nothing in the Mail standards which says a mail address has to be case-insensitive. –  Paŭlo Ebermann Apr 5 '13 at 19:40

Your worst case scenario is that all $18$ characters in the Base64 string are letters — this allows for $2^{18}$ possible collisions due to case-insensitivity. A normal SHA-1 hash is $160$ bits, and therefore has $2^{160}$ possible combinations. Divide by the number of collisions, and you have an effective strength of $142$ bits.
As Stephen Touset explains, this is perfectly fine and completely safe. There is no need to update the email addresses everyone is using. The security level you achieve is basically that of a 142-bit MAC, so an attacker who tries to guess a MAC value (with one try) has about a $1/2^{142}$ chance of success. That's a sufficiently small number that the system will be secure in practice, even using a case-insensitive comparison. So, no need to change what you are currently doing, if the change would cause problems for your users -- what you are already doing is safe enough.