Here’s something that’s bugged me for a long time… the overuse of encryption when hashing will work just fine.
For example, let’s say that I build a redirect URL that contains something in the URL that isn’t particularly sensitive information, but I don’t want anyone messing with. Let’s say I generate a coupon code and an expiration date.
Maybe that’s a silly example, but oh well.
But I don’t want to send it like that, because someone could intercept the URL, change the date to 2211/01/31 or something, and reuse that code for the next 200 years.
Now, the knee-jerk reaction is to say, “Encrypt it!” But that adds a lot of headaches. Encryption is slow. Encryption requires some sort of key management. Encryption bloats the size of your messages.
Instead, I can just take my generated URL, run it through a salted SHA1 hash, and encode some piece of the digest as ASCII and add that to the URL. Or you could encode the whole digest, but that’s probably more bytes than you need.
SHA-1 is fast. Too fast, as it turns out, to be useful for some cryptographic tasks like protecting passwords. But in this case, fast is good.
The server generates the hash using the input string plus a “salt” string, which is just a secret phrase that only the client and server know. A man in the middle can’t change the values and regenerate the hash, because he doesn’t know the salt. But the server does know the salt, so he can calculate the hash using the salt, and compare to see if he got the same signature as before. Done!
It just drives me a little batty whenever a team wants to send information around, and become convinced that encryption is an absolute requirement. No. Think about where it makes sense, and where you don’t need to hide the data, and you’re better off just matching hashes on both ends.
Here’s more information on using a cryptographic salt string: