So I've made some great progress by encrypting and sending data between two sites, and the other is site able to decrypt and read the data. I'm on Google App Engine/Python/Django-nonreal, and this page was a great resource for getting pycrypto to work: http://code.activestate.com/recipes/576980/ Kn

So I'm comfortable with knowing user data is encrypted and that you need to have the key to read it, but how could Website2 KNOW that the request came from Website1? What's stopping a hacker from sending the exact same request again, and Website2 thinking this hacker is valid to do stuff on Website2?

For example, couldn't someone just listen in on the http request and record what the encrypted data was send across the line? And then the hacker could do their own request, with the same values that Website1 used before, and the hacker could do the same things to Website2 that Website1 could? Essentially the hacker would be telling Website2 that they are a valid signed-in user of Website1.

Overall Goal: Website2 is told user data which only comes from requests from Website1. Any other requests from a hacker that uses the same encrypted data Website1 sent to Website2 won't work unless your Website1.

Not sure if I explained well enough, or if its a pretty basic understanding that I just don't have, but thank you for your help.

2 Answers
2

In order to prevent replay attacks, you'll need to include a nonce and MAC (Message Authentication Code).

The MAC can simply be a HMAC-SHA1 of the encrypted message contents. The receiving side will compute the same MAC and make sure it matches. The key for the HMAC-SHA1 must be a secret known to both sides. This step is important - just because your data is encrypted doesn't mean it can't be tampered with. In particular, if the attacker can alter just the nonce (see next), you'll have problems. So use a proper MAC.

The nonce should be within the encrypted portion of the message, and used only once ever. The receiving end should record the nonce and reject any future messages with the same nonce. This is the key to preventing replay attacks.

You can avoid having to keep an infinite amount of nonces by also attaching an expiration date to the nonce. Messages received after the expiration date should be rejected. Nonces can be deleted from the seen-nonce database after the expiration date, plus a few hours to account for possible clock differences, passes.

Generating the nonce can be tricky to do properly. Here's one technique:

When your app server starts, create a new dummy datastore entity. Cache its key, as well as your startup timestamp, until your app server terminates. Also create a counter initialized to 0.

When you need a nonce, generate it by hashing (entity key, startup timestamp, counter). Then increment the counter.

You may delete the dummy datastore entity after a period longer than the greatest amount of expected clock drift passes. A few hours should be plenty.