Introduction

The security of data has become a recurrent topic in computer science. I think all software developers in their careers have to study that topic. I always keep informed about that, and I apply various kind of algorithms into the several applications customers ask me to develop.

One of the algorithms I frequently use is the RC4.

RC4 is a stream cipher symmetric key algorithm. It was developed in 1987 by Ronald Rivest and kept as a trade secret by RSA Data Security. On September 9, 1994, the RC4 algorithm was anonymously posted on the Internet on the Cyperpunks’ “anonymous remailers” list.

RC4 uses a variable length key from 1 to 256 bytes to initialize a 256-byte state table. The state table is used for subsequent generation of pseudo-random bytes and then to generate a pseudo-random stream which is XOR-ed with the plaintext to give the cipher text. Each element in the state table is swapped at least once.

The RC4 key is often limited to 40 bits, because of export restrictions but it is sometimes used as a 128 bit key. It has the capability of using keys between 1 and 2048 bits. RC4 is used in many commercial software packages such as Lotus Notes and Oracle Secure SQL. It is also part of the Cellular Specification.

I’ve noticed that nobody provided a C# version of RC4 algorithm, so I’ve done it.

Algorithm description

The RC4 algorithm works in two phases:

key setup

ciphering.

Key setup

Key setup is the first and most difficult phase of this algorithm. During a N-bit key setup (N being your key length), the encryption key is used to generate an encrypting variable using two arrays, state and key, and N-number of mixing operations. These mixing operations consist of swapping bytes, modulo operations, and other formulae.

In the attached project you can see how I do it in the EncryptionKey set property of RC4Engine class.

Chiphering phase

Once the encrypting variable is produced from the key setup, it enters the ciphering phase, where it is XOR-ed with the plain text message to create an encrypted message. XOR is the logical operation of comparing two binary bits. If the bits are different, the result is 1. If the bits are the same, the result is 0. Once the receiver gets the encrypted message, he decrypts it by XOR-ing the encrypted message with the same encrypting variable.

In the attached project you can see how I do it in the RC4Engine class:

Encrypt: encript method

Decrypt: decript method

I want to remark that the cripted message comes decrypted using the algorithm used in the encryption phase.

How does the application work?

The front-end layout is the following:

You can:

Enter in In Clear Text Box, a text that has maximum 32767 characters

Click the Encrypt button that appears after you have filled the In Clear Text Box.

To verify the Crypted Text Box you can click the Decrypt button that appears at the end of the encryption process.

You can also modify the encryption key but make sure to use it for both encrypting and decrypting the text.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A: I tried yours and used a key and clear text to encrypt and then decrypt. I get the same clear text.

B: I downloaded another rc4 algorithm and used the same key and clear text. That works fine.

When I put the encrypted text from your (A) into the decryption of (B) the clear text is different. Likewise if I put the encrypted text from (B) into (A) the clear text is different.

If both bits of code are supposedly RC4 compliant would you agree that providing I use the same key and clear text (which I did) I should get the same output for the encrypted and decrypted text?

I don't know then if there's more than one flavour of RC4 which is unlikely, or perhaps it's related to the key size or some other internal factor or perhaps one of the algorithms isn't telling the truth!

How would you verify which is right and which is wrong?

If there is one thing more dangerous than getting between a bear and her cubs it's getting between my wife and her chocolate.

The problem I later found is that I believe the algorithm for RC4 has never been officially divulged and has been isolated by reverse engineering and other cryptanalysis techniques. The device I worked on uses RC4 and after finding one implementation of several did I find one that was compatible. The other three I tried all "failed" even though they worked "correctly". Why they don't officially release the algorithm is puzzling. After all, it's not, by all accounts, that secure anymore.

If there is one thing more dangerous than getting between a bear and her cubs it's getting between my wife and her chocolate.

I am a developer working for a commercial software company. I am interested in adapting source code found in this article. Can you tell me if there are license or copyright terms with which I must comply?

Thanks Simone for this article, but actually I have a comment about the algorithm implementation,
you are using 'mod 255', while I've read the algorithm before & it says to use 'mod 256'
that differs in the output completely, so do you have any explanation for wt you've done or that was a mistake?
Thanks,

hello.....i`m now doing my final year project in my university.....and i have to do the encryption and decryption via the PIC microcontroller....could anyone help me how could i do my project or any references or tutorial.....I`m gonna do it in C language programming.......

Your example was exactly what I was looking for. A small and simple (and working) encryption class for a small and simple tool that needs to hide a password in its settings file. All the other examples I've found using Microsoft's encryption API were just too complicated for a beginner. You've really made my day!

When you encrypt it it loses part of the message and when you decipher you got only

It's a bug of the interface: it doesn't display all the crypted phrase. The encryption class works fine : if you want to test it you have to debug the project and set breakpoint to line 314/315 of frmFrontend.cs.
Hope it heps.

The RC4 algorithm works very well, but I need to hold the text in a file and then load it and descrypt it. What kind of file I need for that ?

I tried using a simple StreamFile in C#, but when I load the text again, and try to descrypt it, the result isn't the first text typed by myselft(I think the troubles are due to the encryption characters).

I am having the same problem. I tried using all kinds of methods to do the trick but the ciphertext is not converted back to the original plaintext. I guess the problem lies in picking up the special characters from the text file and then trying to decrypt them using this algo. There are so many packages that do encryption and store it to a file so I guess there must surely be a way via which this could be achieved. I really need an answer pronto!

I've just completed writing a little encryption program that allows you to load text into a text control, encrypt it and save it again. I wrote the original in WINAPI C and found the problem you mentioned when I translated it into CSharp. I found that the 'Line ' methods of the StreamReader, StreamWriter and TextBox classes added carriage return characters ('\r\n') to terminate the lines. The way round this is to read the whole stream from a text file into a single string using the ReadToEnd method. Store the string as a buffer and load it into the the textbox with Text and not Lines even though it is multiline. You can change the text and refresh the buffer with the modified text. Process the buffer with RC4 and store the result again as a string in the buffer. Display and save from the buffer - don't display and then take the text from the display for storing as Windows alters it in mysterious ways. Save the string using the Write method and it should work. Hope that helps.

Ti

ps I used a modified version of a C function for the RC4 engine. You can find it on
www.cr0.net:8040/code/crypto/rc4/

Hey, I was just reading over your post, and I seen that you have found a solution to the saving and loading files problems. I was wondering if you had your source code posted anywhere online. Your help would be greatly appreciated.

We saw your coding(c# version).We are doing our final project(B.E-CSE) in WEP.It will be more helpful to us if u send us the original code(C version) of RC4 algorithm and its explanation for our reference.We assure that we will not misuse the code in anyway.
Thank you

I had a question about the size of the encrypted string that is created. In running the windows program, the cipering and deciphering work as advertized; however, when I deploy the ciphered string to a field in a database, I nottice that whenI attempt to log in and decipher the ciphered password, I get a failure. Thisa happens when the cleartext password exceeds 6 characters. Could it be that the ciphered copde is in utf format and that there is not a simple 1-to-1 correspondance between the clear text and the ciphered code? Is is getting truncated? I noticed that when I select * from the database, the next field is offset, in other words the column reporting format is pushed to the right.

It is nice to see the algorithm in C#, however .NET already has a strong, thought native wrapper of good algorithm like http://csrc.nist.gov/CryptoToolkit/aes/rijndael/

It would habe been better if you had derived your class from System.Security.Cryptography.SymmetricAlgorithm

Also do not spend time creating keys from the user string in the RC4 code. Your method is not verified and can be week. Init the engine with byte arrays and leave it up to the user to find a proper way to convert strings to byte keys.

Hope you have time to do this for RC4 and other algorithms . There seem to be more info for other encryption algorithms at http://www.eskimo.com/~weidai/scan-mirror/cs.html

Thank you very much for your suggestions.
I know both the native wrapper and the System.Security.Cryptography.SymmetricAlgorithm and I used them in my development project. That article should be only a starting point. It is only a demo project.
Bye,
Simone

There is a ARCFOUR managed implementation, based on System.Security.Cryptography.SymmetricAlgorithm, available in Mono (http://www.go-mono.com/). It is part of the assembly Mono.Security.dll (with other security/cryptography) related classes.

Also all the .NET cryptographic algorithms (DSA, RSA, RC2, AES, DES and TripleDES) are available in managed versions (as part of Mono's corlib).

I found RC4 really there and some of the secure hashing algorithms implemented properly in C#, but Mono still seem to call CryptoAPI in some places for Win32 implementation (Mono.Security.Win32), as can be seen in Mono.Security.Cryptography.CryptoAPI

Further more I am not sure if they have re-writen any of System.Security.Cryptography classes found in corelib.dll, or they are from the original .NET implementation.

You're welcome. However you are wrong on many issues. More details on the Mono's cryptography can be found here.

peter_s111 wrote:but Mono still seem to call CryptoAPI in some places for Win32 implementation (Mono.Security.Win32),

Mono.Security.Win32 is a wrapper for CryptoAPI that works only under Windows. But it's not normally used by Mono (in fact it's only current use is to get good random numbers under Windows as the Linux version uses /dev/[u]random) but it also include access to CryptoAPI hash algorithms. Some people have shown interest to build other wrappers for OpenSSL and NSS (for either performance reason, certification or compatiblity with HSM - Hardware Security Modules).

This is why I suggested to look in Mono.Security.dll (for ARCFOUR) and corlib.dll assemblies (for RSA/DSA/AES/...) but not in Mono.Security.Win32 which is not very interesting for MS.NET users.

peter_s111 wrote:I am not sure if they have re-writen any of System.Security.Cryptography classes found in corelib.dll

Yes we have . Many people have contributed and I've myself done a lot of work on them. The original BigInteger code, required for RSA and DSA, was found here in The Code Project and had since been very much optimized by BenM.

peter_s111 wrote:or they are from the original .NET implementation

That's quite an unfair and unbased comment, however it's an easy one to dismiss because the original .NET implementation use CryptoAPI (and hence isn't portable outside Windows) while the Mono implementation is 100% managed C# code. Guess we didn't have a choice to re-write the stuff