0xPoly / Centry

Panic button for protection against cold boot attacks
GNU General Public License v3.0
139 stars 24 forks source link

end-to-end encryption #5

Open johannestaas opened 10 years ago

johannestaas commented 10 years ago

An attacker who can MITM the connection can obtain password hashes that they can crack offline, or replay the traffic for undesirable consequences (separate issue).

Might be possible to use this: https://pypi.python.org/pypi/Dtls/0.1.0

Some sort of real authentication with secrecy and integrity checking would be better.

0xPoly commented 10 years ago

Is there a way to implement DTLS for broadcast? Because my understanding is that TLS over UDP requires a handshake with each host, which can be tedious to do if you are connecting to a large number of nodes.

johannestaas commented 10 years ago

Ouch... Not sure. Bottom line though, you don't want people reading what you send, you shouldn't need to send it plaintext, and you step into a very dangerous realm once you start working with crypto primitives on your own, like an AES cipher, hash, etc. Crypto is extremely hard to get right, and professionals will generally suggest that you either use openSSL or GPG and not touch lower level implementations.

Okay, one attribute of your tool is that you don't want to have to do a handshake. Not only is it not convenient, but it's probably less secure. What if an attacker sees the incoming connection and breaks the handshake? You should be able to send one UDP bullet and kill the device immediately. Unless something exists that will be able to do this for you, you're somewhat forced to roll your own crypto. It won't be hard to make it run, just extremely hard to make it so that it can't be messed with.

You will need secrecy, integrity checking, and authentication. One possible route is AES256 with an HMAC. That might look like this:

IV = 8 bytes from /dev/urandom PANIC_CYPHERTEXT = AES256(aes_key, PKCS5("mysecretpanicphrase"), mode=CBC, iv=IV) UDP_PAYLOAD = HMAC(IV + PANIC_CYPHERTEXT, hmac_key)

All lowercase supplied by user.

Now, how do we make this immune to replay attacks?

Here's one way, that will work 5 times. Take an original aes_key, and hash it, to get hash(key). Now hash that to get hash(hash(key)) What happens is the service will expect the first time to get hash(hash(hash(key))). Once it gets that, it subtracts one layer. Now the program expects just hash(hash(key)), all the way until hash(key), which is when the key expires.

The key changes, but it's based on one key you supply, and once you triggered it to a device, they can only replay it to devices that haven't seen the first one, which may be actually desirable in this case. Seeing it to one will effectively broadcast it to the rest if the attacker replays it, but they can't continuously replay it to DoS the devices, unless they figured out the original key, and even then they could only do it x number of times.

NOW... the best thing is still to find a reputable module that has already implemented a way to do all this via UDP for you, something that is maintained by someone who knows how to code secure crypto. If not, you might be stuck doing it yourself and then submitting the scheme to /r/crypto to ask for advice, but expect to hear a lot of "don't roll your own crypto". In fact, it's best to submit your scheme there before prototyping it because they might find a major flaw.

But first, try to find a suitable module made by a reputable crypto dev. I'm just a hobbyist.

Cheers, Johan

On Tue, May 27, 2014 at 1:37 PM, Poly notifications@github.com wrote:

Is there a way to implement DTLS for broadcast? Because my understanding is that TLS over UDP requires a handshake with each host, which can be tedious to do if you are connecting to a large number of nodes.

— Reply to this email directly or view it on GitHubhttps://github.com/0xPoly/Centry/issues/5#issuecomment-44331940 .