views:

883

answers:

7

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...

+1  A: 

I'd probably go for AES.

JesperE
+2  A: 

AES 256 is generally the preferred choice, but depending on your location (or your customers' location) you may have legal constraints, and will be forced to use something weaker.

Also note that you should use a random IV for each communication and pass it along with the message (this will also save the need for a timestamp).

If possible, try not to depend on the algorithm, and pass the algorithm along with the message. The node will then look at the header, and decide on the algorithm that will be used for decryption. That way you can easily switch algorithms when a certain deployment calls for it.

On Freund
Initialization Vector (http://en.wikipedia.org/wiki/Initialization_vector)
On Freund
Sending the algoritm with the message is not a great idea, its too hard to do right. This could lead to downgrade attacks, not pretty. SSL3 prevents this, but it was a common attack in SSL2.
AviD
You can circumvent the downgrade attack by setting a minimum.
On Freund
But why would you need the dynamic setting? If you control all the nodes, just set a single, minimum algorithm which is strong enough for your needs.
AviD
Some of the nodes might have different regulatory constraints. In that case you want all your nodes to use the strongest encryption possible, but you're aware that some nodes will have to use weaker encryption.
On Freund
+1  A: 

Asymmetric encryption would work in this scenario as well. Simply have each node publish it's public key. Any node that wants to communicate with that node need only encrypt the message with that node's public key. One advantage of using asymmetric keys is that it becomes easier to change and distribute keys -- since the public keys can be distributed openly, each node need only update it's public-private key pair and republish. You don't need some protocol for the entire network (or each node pair) to agree on a new symmetric key.

tvanfosson
What about performance? I fear asymmetric encryption will cost a lot for loads of small comments...
Daren Thomas
I think that using asymmetric encryption would defeat the purpose here - if I understand correctly, the whole network is to be deployed with one shared secret. With asymmetric encryption, you'll have to add some authentication mechanism to to make sure that only "legal" nodes can participate.
On Freund
Yes, asymmetric would cost significantly in performance. Only you know whether this would be acceptable in your application. I was just observing that asymmetric encryption would work and probably be less complex with respect to key management.
tvanfosson
I'm assuming that you already know which nodes belong to the network or there is some protocol that guarantees that only legal nodes can join. You could guard against false messages from outside the network by having each message signed by the private key of the sending node.
tvanfosson
I am not recommending asymmetric encryption, but the performance problems can be avoided. Normal practice is to transmit a single-session symmetric encryption key using asymmetric encryption, then switch to symmetric using that session key. This has all the benefits of each system.
Jeffrey L Whitledge
+3  A: 

Assuming the use of symmetric crypto, then AES should be your default choice, unless you have a good very reason to select otherwise.

There was a long, involved competition to select AES, and the winner was carefully chosen. Even Bruce Schneier, crypto god, has said that the AES winner is a better choice than the algorithm (TwoFish) that he submitted to the competition.

skaffman
And if you aren't following Schneiers blog, you should: http://www.schneier.com/blog/
JesperE
+1  A: 

Why not create a VPN among the nodes that must communicate securely?

Then, you don't have to bother coding up your own security solution, and you're not restricted to a static, shared key (which, if compromised, will allow all captured traffic to be decrypted after the fact).

fcw
+6  A: 

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 ;-).

AviD
I would prefer not to do channel security, as I'd have an exponentially growing list of channels (P2P Network). Building a channel for each message is also not feasible, as this happens often and only for short messages.
Daren Thomas
Ah, if its an open P2P network IPSec wouldnt be relevant, thats really only good inside a controlled network.
AviD
+4  A: 

"I haven't a clue about encryption at all. But I need it. How?"

DANGER! If you don't know much about cryptography, don't try to implement it yourself. Cryptography is hard to get right. There are many, many different ways to break the security of a cryptographic system beyond actually cracking the key (which is usually very hard).

If you just slap a cipher on your streaming data, without careful key management and other understanding of the subtleties of cryptosystems, you will likely open yourself up to all kinds of vulnerabilities. For example, the scheme you describe will be vulnerable to man-in-the-middle attacks without some specific plan for key distribution among the nodes, and may be vulnerable to chosen-plaintext and/or known-plaintext attacks depending on how your distributed system communicates with the outside world, and the exact choice of cipher and mode of operation.

So... you will have to read up on crypto in general before you can use it securely.

Dan