Re: RC4 algorithm problem

From: Michael Amling (nospam_at_nospam.com)
Date: 05/22/03


Date: Wed, 21 May 2003 23:23:53 GMT

aneesh wrote:
> Hi everybody,
> Im using RC4 algorithm(C++ implementation) to encrypt a file. But when
> i decrypt the file with the corresponding java implementation the
> results are unpredictable. Sometimes it work some times not. What will
> be the problem.
> The algorithm is given below.
>
> #######################
> java implementation
> #######################
>
> class RC4 {
>
> int lengthOfKey;
> int lengthOfData;
> byte key[];
> short state[] = new short[256];
>
> public RC4(String Key, int Length) {
>
> this.lengthOfData = Length;

   Why have this parameter? The value you set here for this.lengthOfData
always gets overlaid in cipher().

> this.key = Key.getBytes();

   getBytes() returns different results depending on the the platform's
default character encoding, at least when any of the characters are out
of the ASCII range 0x0000..0x007F.
   Is using an ASCII string directly as the RC4 key a recommended practice?

> this.lengthOfKey = this.key.length;
>
>
> }
>
> public String encrypt(String plainText)
> {
> setup();
> return cipher(plainText);
> }
>
> public String decrypt(String plainText)
> {
> setup();
> return cipher(plainText);
> }
>
> void setup()
> {
>
> int num1,num2,index1 = 0, index2 = 0;
> short tmp =0;
>
> for ( num1= 0; num1 < 256; num1++)
> state[num1] = (short)num1;
>
> for ( num2 = 0; num2 < 256 ; num2++){
> index2 = (((int)key[index1] &
> (int)0xff)+state[num2]+index2) & (int)0xff;
> tmp = state[num2];
> state[num2] = state[index2];
> state[index2] = tmp;
> index1 = (index1 + 1) % lengthOfKey;
>
> }
>
> }
>
> String cipher(String IPData){
>
> int x = 0,y = 0,b = 0;
> short temp = 0;
> byte data[] = IPData.getBytes();

   If IPData has any chars outside of the range 0x0000..0x007F, then
getBytes() may not be returning what you think it does.

> this.lengthOfData = data.length;
>
>
> for(int index = 0;index<lengthOfData;index++){
> x = (x+1)& (int)0xff;
> y = (state[x]+y) & (int)0xff;
> temp = state[x];
> state[x] = state[y];
> state[y] = temp;
> b = (state[x] + state[y]) & (int)0xff;
> data[index] = (byte)(data[index] ^ state[b]);
>
> }
> return new String(data);

   new String(byte[]) is definitely a bad idea. It's going to interpret
uniform binary data according to the platform's default character
encoding. The original binary data, if it forms an invalid character
encoding, may not be recoverable from the the resulting sequence of char.
   Far better to make the parameter a byte array, which is very easy to
do I/O with, easier than String.
   If you insist on storing binary data in a String, use the deprecated
new String(byte[], int) and the deprecated void getBytes(int, int,
byte[], int), which are deterministic and independent of any character
encoding.

> }
> }

--Mike Amling



Relevant Pages