RC4 Cypher Algorithm in C#
[stextbox id=”info” caption=”Comment or Leave a Message”]
Please Comment or Leave a Message if this is what you are looking for or if you have any question/comment/suggestion/request.
[/stextbox]
RC4 is the most widely used symmetric cypher algorithm, especially given its performances.
The Key is generally between 5 and 16 bytes, equivalent to 40-128 bits.
Initialisation
To initialise the algorithm it is used a permutation of all 256 possible byte values using the Key-Scheduled algorithm.
The procedure is quite simple. Assuming that we have our key stored in an array that we can access (let’s call this array simply “key”), we have to:
- Initialise an array with the identity permutation of the 256 values (let’s name this array simply as “buffer” for now)
- Loop through each array element (let’s assume that “i” is the index of the array for the element currently processed) in this way:
- Use another index “j” (initialised to 0) and add to this index the element in the i-th position (buffer[i])
- Add to the result the content of the key buffer in the i-th mod key-length position (or “i % keylength” if you prefer). This essentially means the value in: key[i % keylength]
- Ensure that we never end outside our buffer boundaries. Take the value of j % 256 (or j & 255 if it sounds cooler to you)
- Swap buffer[i] with buffer[j]
The code sample shows this algorithm in action:
1 2 3 4 5 6 7 8 9 10 11 12 |
byte[] buffer = Enumerable.Range(0, 256) .Select(i => (byte)i) .ToArray(); for (int i = 0, j = 0; i < 256; i++) { j = (j + key[i % key.Length] + buffer[i]) & 255; byte c = buffer[i]; buffer[i] = buffer[j]; buffer[j] = c; } |
Encryption
Once initialised the algorithm using our key we are ready to encode the message.
This algorithm could seem a little bit more convoluted, but it is actually quite simple.
Let’s assume that the message to protect is stored in an array called “message”. The steps are those:
- Reset i and j to 0
- For each byte of the message that we want to encode do the following:
- Increment i and keep it in our buffer boundaries: i = (i + 1) % 256
- Add buffer[i] to j keeping the result in the array as well: j = (j + buffer[i]) % 256
- Swap buffer[i] with buffer[j]
- Add the values in buffer[i] and buffer[j], keep the result in the buffer array range: (buffer[i]+buffer[j]) % 256
- Use it (let’s name it “encryptionByteIndex”) as an index in buffer itself: encryptionByte = buffer[encryptionByteIndex]
- Use the value of the buffer in this position to xor the current byte of the message: encryptedMessageByte = message[currentIndex] ^ encryptionByte
- Store this in an encryptedMessage buffer: encryptedMessage[currentIndex] = encryptedMessageByte
At the end of this algorithm the message will be encrypted in the buffer encryptedMessageBuffer. In order to decrypt it we can follow the same procedure using this buffer as our input buffer.
This is one code sample (in this code I will use only one buffer for the message and its encryption):
1 2 3 4 5 6 7 8 9 10 11 12 |
int i = 0; int j = 0; for (int x = 0; x < message.GetLength(0); x++) { i = (i + 1) % 256; j = (j + buffer[i]) % 256; Byte temp = buffer[i]; buffer[i] = buffer[j]; buffer[j] = temp; temp = (buffer[i] + buffer[j]) % 256; message[x] ^= buffer[temp]; } |
If you want to see where this could be useful have a look at my other blog entry here: Crypt in C++ and Decrypt in C# (and C++).