When I stumbled over yet another article on how you get your cryptography wrong, I remember that I did something similiar myself.
No, not the broken scheme from that article, but I had needed to use some crypto functions to verify some data that had been handed to the user before.
The problem was similar to the one above: I had to stuff some session data into a hidden field on the page. When it was re-submitted, I needed to make sure that the incoming data blob had been tampered with by the user. Meaning that I needed to verify if a given piece of data actually came from a trusted source.
Reviewing my code, it doesn’t look too bad: I didn’t use some strange shared-key encryption scheme. In fact, I didn’t use encryption at all – if your data is “secret”, you probably shouldn’t send it out to the user in the first place. Instead, I’m just encoding and zipping the data and then slab a MAC (Message Authentication Code) on it. I’m passing the whole stuff of to OpenSSL, so the implementation should be reputable enough.
It’s more or less the same mechanism that Rails uses for it’s session cookies. I even added a nifty little feature that the secret key is automatically generated on the first startup, so there’s no default value that you have to change.
Still there could very well be a bug, and the evil thing about crypto bugs is that you never notice them, and you can’t test for them either. So I’m posting the code below – have a go and see if you find an exploit.
The weaknesses I’ve seen so far:
- I’m still using MD5, as it is the most portable at this time. While it has been successfully cryptanalysed, cracking it will still take more effort than it’s worth for the sites I’m working on. Plus there, are probably more promising angles of attack. Nonetheless, it’s a no-brainer replacing the algorithm when needed.
- There’s no protection against replay attacks, as I simply didn’t consider it important for the application.