I want to encrypt my network communications with RC4. The reason for choosing RC4 is the simple implementation and speed.

I need to have a pure Python implementation, because I cannot compile for my target system. My implementation is slightly modified from TLS Lite.

If I understand the security issues correctly, the main problem is that the algorithm is not designed to be used with a nonce. As proposed at Wikipedia, my approach is to generate an MD5 hash of the key and a nonce and use this as encryption key.

Is this enough or do I have to implement the dropN variant, too? Any other weak spot I have to look at?

A fast and simple alternative to RC4 would be appreciated, too.

Update After reading Cryptology ePrint Archive: Report 2002/067, I think I should definitely use the dropN approach (with at least 512 bytes).

Update 2 Reviewing my implementation would also be nice.

  • Doesn't python contain c implementations of crypto, say AES? Wouldn't that be just as portable, and faster? – CodesInChaos Jun 19 '12 at 13:07
  • @CodeInChaos read the question carefully: "because I cannot compile for my target system" – schlamar Jun 19 '12 at 13:37
  • Somebody already compiled python for the target system. Doesn't the python standard library contain a pre-compiled crypto library? I'd expect that from most modern programming languages. – CodesInChaos Jun 19 '12 at 13:52
  • No, not on older Python versions. From Python 2.6 on there is SSL built-in, but I have to support Python 2.3. – schlamar Jun 19 '12 at 14:03

First: Do NOT use MD5. Ever. Never. Especially not in any form of security contexts. Use at least SHA-1 or SHA-2 (256 or 512/256 if speed is an issue on 64-bit machines). Apart from some legacy reasons, MD5 should be banned and the faster you stop using it the better you are off.

If you need a simple, pure Python RC4 implementation I have one at http://www.strombergson.com/files/rc4_gen.py.gz.

It is basically the same implementation we used as one of the sources for the test vectors in RFC 6229.

Yes, you should use nBytes. Look at the arcfour128, arcfour256 defined in RFC 4345 or some of the others we have calculated test vectors for.

I realise that I should move the RC4.py to GitHub. And change the fingerprint to using something other than MD5. Facepalm. ;-)

  • Ok, thanks for the links. My implementation is pretty much the same but the test vectors are very useful and the advice to drop the first 1536 bytes is new, too. – schlamar Jun 19 '12 at 15:41
  • If MD5 is not secure, you should tell Mozilla to turn off "security.ssl3.rsa_rc4_128_md5" by default. – curiousguy Jun 19 '12 at 19:01
  • Maybe you want to review my version (question updated). – schlamar Jun 20 '12 at 8:00
  • I took a look at your implementation and it looks like a clean, simple implementation. I would suggesrt adding some KATS from RFC 6229 to show that it works. And some documentation. – Joachim Strömbergson Jun 20 '12 at 8:30
  • Regarding md5 in SSLv3 you can disable these suites in your broswer. I would assume Mozilla knows about the status of md5, but includes it due to legacy support reasons. – Joachim Strömbergson Jun 20 '12 at 8:32

RC4 has a few shortcomings:

  • It has no Initialization Vector distinct from the key. If you use the same key twice, then you get twice the same sequence of pseudo-random bytes, and using that is a deadly sin. Thus, each key should be used only once (for a possibly long stream of bytes). Deriving the encryption key from a "master key" and a per-message random value, using a key derivation function (e.g. a hash function), can correct that if done properly.

  • It has rather big biases in the first bytes. Dropping the first N bytes of output (for some value of N which should be a few hundreds) can fix that.

  • It has small biases afterwards. These can be statistically exhibited over a few gigabytes of data. There is no known cure. These biases are rarely fatal.

  • RC4 is encryption only. It does nothing for integrity. In any serious attack model, encryption must be coupled with a MAC. Combining a symmetric cipher and a MAC securely is not easy.

For all these reasons, the best way to use RC4 is often not to use it at all. Instead, use an authenticated encryption mode which does all the hard work; my favourite is EAX.

As for performance, consider that modern x86 CPU offer an hardware implementation of AES against which RC4 will be an arthritic snail. If you nonetheless have an actual performance issue on an architecture which does not offer an hardware-optimized AES, then RC4 is not the best in class either; there are other stream ciphers which are both faster and more secure (all the stream ciphers from the current eSTREAM portfolio received a fair amount of scrutiny and went through unscathed).

  • It sounds like the OP is using something like MD5(key||nonce) as RC4 key, so the first point shouldn't affect him too much. – CodesInChaos Jan 3 '13 at 20:26
  • Well, ECRYPT itself doesn't recommend eSTREAM in its annual report – schlamar Jan 7 '13 at 8:03
  • To be fair, ECRYPT says that it is just a bit too early to recommend the algorithms in the eSTREAM portfolio for general usage. They also say that the algorithms raise interest, have received and keep on receiving scrutiny, and that some have probably already been deployed in production by early adopters. My rule of thumb is to wait 5 years between publication and usage; the portfolio has been finalized in 2008 and we are now in 2013, so the algorithms are becoming "ripe" (at least in my own, necessarily subjective view). – Thomas Pornin Jan 7 '13 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.