HTTP based authentication/encryption protocol in a custom system
We have a custom built program that needs authenticated/encrypted communication between a client and a server[both in Python].
We are doing an overhaul from custom written Diffie-Hellman+AES to RSA+AES in a non-orthodox way. So I would be very interested in comments about my idea.
Prequisites: Klient has a 128bit RegistrationKey which needs to remain a secret during the authentication - this key is also the only shared secret between the server and client.
- Client contacts the server over an insecure channel and asks the servers RSA PubKey
- Client then queries the server: [pseudocode follows]
RegistrationKey = "1dbe665ac7a944beb67f106f779e890b"
clientname = "foobar"
randomkey = random(bits=128)
rsa_cp = RSA(key=pubkey, data=randomkey+clientname)
aes_cp = AES(key=RegistrationKey, data=RegistrationKey+rsa_cp)
send(aes_cp)
3. Server then responds:
[pseudocode follows]
# Server decrypts the data and sees if it has a valid RegistrationKey, if it does...
clientuuid = random(bits=128)
sharedkey = random(bits=128)
rsa_cp = RSA(key=privkey, data=clientuuid+sharedkey)
aes_cp = AES(key=randomkey[got from client], data= rsa_cp)
send(aes_cp)
Now both sides know the "clientuuid", "sharedkey" which the client can use later to authenticate itself. The method above should be secure even when the attacker learns the regkey later since he would have to crack the RSA key AND man-in-the-middle attacks(on RSA) should stop the auth. from completing correctly.
The only possible attack method I see would be the case where the attacker knows the regkey AND can alter the traffic during the authentication. Am i correct?
I really want to hear your ides on what to add/remove from this method and If you know a much better way to do this kind of exchange.
PS! We are currently using Diffie-Hellman(my own lib, so it probably has flaws) and we have tried TLSv1.2 with Pre开发者_C百科SharedKeys(didn't work for some reason) and we are CONSTRICTED to http protocols since we need to do this in django. And because we are doing this in http we try to keep the request/answer count as low as possible(no sessions would be the best) - 1 would be the best :)If you have any questions about the specifics, please ask.
So, you crypto/security geeks, please give me a helping hand :)
Don't re-invent the wheal, use HTTPS.
The server can issue certificates to the client and store them in the Database. Clients can be distributed with the server's self-signed certificate for verification. The server can verify clients by using Apache's HTTPS Environment Variables.
No. Use SSL. Reinventing cryptosystems is a bad idea.
What you can easily do is set up a reverse proxy. Run your Django app on a higher port (e.g., 8080) and set it to respond only to connections from the loopback address (127.0.0.1). Run the reverse proxy on port 443 (standard HTTPS port) and proxy all requests to the Django app. But setup the reverse proxy with the site's certificate and have it be an SSL endpoint. The proxied requests going to the Django app would then just be "regular old" HTTP, not HTTPS.
Apache Mod_Proxy
NginX as a Reverse Proxy
- I don't think RegistrationKey adds any real security.
- It needs more nonces (against replay attacks).
- It needs more padding (or else the messages are small and thus easy to decrypt).
- An algorithm can be proven to be secure, you may want to do this.
- Most flaws in crypto are in the implementation, not in the algorithm (timing attacks, for example).
精彩评论