tags:

views:

267

answers:

1

I have a server (RoR app) sending information to a client (a Ruby Sinatra app) and I need a way for the client to be certain the data has come from my server, rather than an evil third party.

The client has to login to the server before anything will be sent back the other way so the server could reply to the login with a shared key used to sign all further responses, but then the 3rd party could capture that response and be evil.

I'd like to find some way (in Ruby, with a view to cross-platform applicability) to sign the server's response so that it can be verified without inspection of the client's code leading to forgeries. Any ideas?

UPDATE: Lets see if I can explain this better!

(I've added code to github since I wrote this question, so you can (if you like!) have a poke around : The 'client' The 'server')

The process is this: Joe Bloggs uses a bookmarklet on his mobile device. This posts the currently visited URL to sitesender.heroku.com. When sitesender.heroku.com receives that request it checks its DB to see if anyone has logged into the same account using the Target application. If they have, their IP address will have been noted and sitesender.heroku.com will make a GET request of the target app (a webserver) at that IP asking the target to lanch the bookmarked URL in the default browser.

The basic idea being that you can send a site to your main computer from your iPhone for later viewing when you find the iPhone can't cope with the page (eg. flash, screen size).

Obviously the major issue is that with an open server anyone could send a request to open 'seriouslyevilwebsite.com' to a broad range of IPs and I've unleashed a plague on the digital world. Seeing as I'm using heroku.com as a server (its an incredibly good but cloud based RoR host) I can't just test the originating IP.

As far as I understand HTTPS, for this setting I'd have to sort out certificates for every target application? I agree that I need some form of asymmetric crypto, sign the outgoing requests from sitesender.heroku.com with a private key (never distributed) and get the target to perform the same operation using the public key and test for similarity - but you've guessed correctly, I'm still slightly clueless as to how HMAC works! How is it asymmetric? Is it formulated so that performing the same HMAC operation with the private key and public key will generate the same signature? In which case - HMAC is a winner!

Thanks for your patience!

+1  A: 

I'm not sure exactly what you mean by "freely examined, but not replicated".

In general, if you need a secure communications channel, https is your friend.

Failing that (or if it's insufficient due to some architectural issue), HMAC and asymmetric crypto is the way to go.

UPDATE: I'm not sure I understand the problem, so I will try to describe the problem I think you're trying to solve: You have clients that need to be confident that the response they are seeing is actually coming from your server.

Assuming that I'm correct and this is really the problem you're trying to solve, HTTPS solves it nicely. You install a cert on your server—you can sign it yourself, but clients won't trust it by default; for that, you need to buy one from one of the standard certificate authorities (CAs)—and then the client makes an HTTPS request to your server. HTTPS handles verifying that the provided certificate was issued for the server it's talking to. You're done.

Finally, I think there's a misunderstanding with how an HMAC works. The key principle of asymmetric crypto is to NEVER distribute your private key. With asymmetric crypto, you encrypt messages with the recipient's public key and he/she decrypts it with his/her private key. You sign messages with your private key, and he/she verifies it using your public key.

Hank Gay
Cheers man, seems like HMAC is the way forwards, but if the code to the client is freely available can HMAC cope? HTTPS would be ideal, but as my 'client' (actually a web server) will be on Joe Public's computer, SSL isn't an option.
JP
HTTPS (as typically implemented) only requires a certificate for the server side of the communications. HMAC is typically sufficient for verifying the contents of a message haven't changed, but if you want to make sure nobody in the middle inspects it, you need to encrypt the signed message.
Hank Gay
Inspection isn't a problem, I just need to make sure the messages coming in are from who they should be. I'll read up on HMAC, thanks!
JP
Unfortunately it seems that HMAC won't do the trick, as my client would have to know the private key to be able to compare the server's MAC with what it should be. A malicious coder could extract that private key from the interpreted code and forge a correctly signed request. More thought required on my part - thanks for your help though!
JP