I haven’t a clue about encryption at all. But I need it. How?
Say you have a system of nodes communicating with each other on a network via asynchronous messages. The nodes do not maintain session information about other nodes (this is a design restriction).
Say you want to make sure only your nodes can read the messages being sent. I believe encryption is the sollution to that.
Since the nodes are not maintaining a session and communication must work in a stateless, connectionless fashion, I am guessing that asymmetric encryption is ruled out.
So here is what I would like to do:
- messages are sent as UDP datagrams
- each message contains a timestamp to make messages differ (counter replay attacks)
- each message is encrypted with a shared secret symmetric key and sent over the network
- other end can decrypt with shared secret symmetric key
Keys can obviously be compromised by compromising any single node. At the same time, in this scenario, access to any single compromised node reveals all interesting information anyway, so the key is not the weakest link.
What cypher should I use for this encryption? What key length?
I would prefer to use something supported by ezPyCrypto.
Assuming, as most point out, I go with AES. What modes should I be using?
I couldn’t figure out how to do it with ezPyCrypto, PyCrypto seems to be hung on a moderator swap and googles keyczar does not explain how to set this up – I fear if I don’t just get it, then I run a risk of introducing insecurity. So barebones would be better. This guy claims to have a nice module for AES in python, but he also asserts that this is his first python project – Allthough he is probably loads smarter than I, maybe he got tripped up?
EDIT: I moved the search for the python implementation to another question to stop clobber…
Your first thought should be channel security – either SSL/TLS, or IPSec.
Admittedly, these both have a certain amount of setup overhead, IPSec more than SSL/TLS, especially when it comes to PKI etc. – but it more than pays for itself in simplicity of development, reliability, security, and more. Just make sure you’re using strong cipher suites, as appropriate to the protocol.
If neither SSL/TLS or IPSec fits your scenario/environment, your next choice should be AES (aka Rijndael).
Use keys at least 256 bits long, if you want you can go longer.
Keys should be randomly generated, by a cryptographically secure random number generator (and not a simple rnd() call).
Set the cipher mode to CBC.
Use PKCS7 padding.
Generate a unique, crypto-random Initialization Vector (IV). Don’t forget to properly protect and manage your keys, and maybe consider periodic key rotations.
Depending on your data, you may want to also implement a keyed hash, to provide for message integrity – use SHA-256 for hashing.
There are also rare situations where you may want to go with a stream cipher, but thats usually more complicated and I would recommend you avoid it your first time out.
Now, I’m not familiar ezpycrypto (or really python in general), and cant really state that it supports all this; but everything here is pretty standard and recommended best practice, if your crypto library doesnt support it, I would suggest finding one that does ;-).