These are things I do know (though I don’t understand public/private keys), but since I’m having problems with signing OAuth requests, I figured I’d brain dump my knowledge, filling in any gaps with research and hoping that I’ll understand why my signing isn’t working. If nothing, I’ll have a blog post about encryption to help people. I’ll mostly be talking about encryption to do with OAuth though.
If you’d rather hear about this from someone that knows what they’re talking about, rather than someone who’s building up their knowledge as a lone wolf and possibly going in the wrong direction, then you’ll want this post on security architecture.
OAuth wants to let one website access a user’s private data on another website, using HTTP. That basically means that all requests are made through URLs (either which get parameters, or through post data). That kind of data can be snooped on by malicious people through a man in the middle attack where the data can actually be changed before being sent to the server, or someone could just store it by watching wireless communication, or if you have a virus on your computer/router/access point which is relaying traffic to someone.
For instance, a customer could click the URL:
http://www.orderadrink.com/drink_order.php?drink=tea&customerid=1234
But then an attacker could see the request, and before it gets to the server where the order would be processed, they could change it to:
http://www.orderadrink.com/drink_order.php?drink=coffee&customerid=1234
And then the customer gets coffee for some reason unknown to them… OAuth fixes that problem by hashing the parameters with a salt (passphrase) that only the consumer (the person sending the request) and the service provider (the person receiving the request) knows. For instance, when I signed up for a developer API account with Google they gave me a phrase that I keep secret. Only Google and I know it.
For instance, the consumer and service provider could both decide that they want to do rot13 on all the parameters. So we take “drink=coffee&customerid=1234” and rot13 it making “qevax%3Dgrn%26phfgbzrevq%3D1234″ (we need to do a urlencode() on it too, since it’s a GET parameter). Then we send this URL to make our order:
http://www.orderadrink.com/drink_order.php?drink=tea&customerid=1234&hashed=qevax%3Dgrn%26phfgbzrevq%3D1234
Now, if the hacker decided to change “tea” to “coffee”, orderadrink.com would notice because the parameters no longer match the hashed version, so they wouldn’t allow the action to happen.
Any hacker worth is salt (pun unintended) would immediately notice that that’s just rot13 and would change the hash accordingly. So we use a more sophisticated method of scrambling the parameters. One of those methods offered by OAuth is HMAC-SHA1.
This encrypts the data you give it using a sort of cypher. Damn near impossible to guess, or even to work out. Whilst, it’s not impossible to crack, it’s rarely worth the cracker’s CPU time (which could take years if we’re lucky). So I send the parameters hashed using HMAC-SHA1, using the secret phrase Google gave me, and they just decrypt it to check if the values match up.
I was planning on doing public/private key explanation too, but I really don’t understand it… I’ll go and do more research and maybe do another post on it. I think that’s the problem I’m running into with OAuth; I’ve chosen the signature method that is “more complex and requires key generation and a longer learning curve”. That’ll show me for jumping in at the deep end. I’ll just work with HMAC-SHA1 for a while, which I do understand.