Tuesday, 23 August 2011

RC4 Encryption

Bazinga! I hope that everyone who read yesterday’s ROT13 blog spotted the Sheldon Cooper-esque 'clever prank' for the more secure double ROT13 aka ROT26 algorithm. Today’s blog takes encryption one step further and covers the hugely popular RC4 encryption algorithm developed by Ron Rivest, indeed the RC stands for Ron’s Code. Although now broken, the RC4 algorithm is still widely used in protocols such as SSL and WEP.

The RC4 cipher has two parts: firstly key set up and secondly, data encryption. The key setup is as follows:

for i from 0 to 255
    S[i] := i
endfor
j := 0
for i from 0 to 255
    j := (j + S[i] + key[i mod keylength]) mod 256
    swap values of S[i] and S[j]
endfor

...whilst the data encryption algorithm is:

i := 0
j := 0
while GeneratingOutput:
    i := (i + 1) mod 256
    j := (j + S[i]) mod 256
    swap values of S[i] and S[j]
    K := S[(S[i] + S[j]) mod 256]
    output K
endwhile

The RC4 protocol has been widely documented and more details can be found on Wikipedia from where I copied the above.

The following is what I call my RC4Lite implementation of the above algorithms and it’s called RC4Lite because it really does seem simple:

public final class RC4Lite {

 
private static int MAX_SIZE = 256;

 
private final byte[] state = new byte[MAX_SIZE];

 
public void encrypt(byte[] src, int srcOffset, byte[] dest, int destOffset,
     
int length) {

   
int end = srcOffset + length;

   
int i = 0;
   
int j = 0;
   
int l = destOffset;
   
for (int k = srcOffset; k < end; k++, l++) {
     
i = (i + 1) & 0xff;
      j =
(j + state[i]) & 0xff;
      swap
(i, j);
     
int m = (state[i] + state[j]) & 0xff;
      dest
[l] = (byte) (state[m] ^ src[k]);
   
}

  }

 
private void swap(int i, int j) {

   
byte temp = state[i];
    state
[i] = state[j];
    state
[j] = temp;
 
}

 
public void decrypt(byte[] src, int srcOffset, byte[] dest, int destOffset, int length) {

   
encrypt(src, srcOffset, dest, destOffset, length);
 
}

 
public void setKey(byte[] key) {

   
initStateArray();
    createKey
(key);
 
}

 
private void initStateArray() {

   
for (int i = 0; i < MAX_SIZE; i++) {
     
state[i] = (byte) i;
   
}
  }

 
private void createKey(byte[] key) {

   
int j = 0;
   
for (int i = 0; i < MAX_SIZE; i++) {
     
j = (j + state[i] + key[i % key.length]) & 0xff;
      swap
(i, j);
   
}
  }
}

No comments: