0

I have tried working on the RC4 encryption and decryption procedure. I keep getting an error with the code line s2=key.charAt(j++).
The debugger tells me that it cannot be resolved from char to int.
The output runs untill entering the keystream. The XOR operation is not working out.
Can anyone point out a possible solution?

import java.util.Scanner;

public class Rc4
{

 //global
public static int SIZE=256;



     public static int[] s1 = new int[SIZE+1]; //filled with random numbers
     public static int[] s2 = new int[SIZE+1]; //filled with keytext
     public static int i,j;
     public static String key, input;
     public static void main(String[] args)
     {
          Scanner keyboard= new Scanner(System.in);
          System.out.print("En/Decrypt:");
          input = keyboard.nextLine();
          System.out.print("Enter key :");
          key = keyboard.nextLine();
          INIT();  
          KSA(); 
         }
     static void INIT()
     {
          j=0;
          for(i=0; i<SIZE; i++)
          {          
               if(j==key.length())
                j=0;
                s2= key.charAt(j++);
          }

     }
     static void KSA()
     {
         for( i=0; i<SIZE; i++)
            s1[i]=i;
            j=0;
            for(int i=0; i<SIZE; i++)
            {
                j = (j + s1[i] + s2[i]) % SIZE;
                swap(i, j);
            }
     }
     static void PRGA()
     {
         int Rand=0;
         //print();
         j=i=0;
         for(int x = 0; x< input.length(); x++) 
         {
               i = (i + 1) % SIZE;
               j = (j + s1[i]) % SIZE;
               swap(i, j);
               Rand = (char)s1[ ((s1[i] + s1[j]) % SIZE)];
               System.out.print((char)(input.charAt(x) ^ Rand) );
         }

     }
     static void print()
     {     
         System.out.print("\n");
         for(int y=0; y<input.length(); y++)
            {
              System.out.print(input.charAt(y));
            }
              System.out.print("\n");
     }
     static void swap(int i, int j)
     {
          int temp = s1[i];
          s1[i]= s1[j];
          s1[j] = temp;

     }
}
cHiMp
  • 113
  • 6
user3040432
  • 1
  • 1
  • 1
  • 1

2 Answers2

3

You can use Hex and binary conversion of org.bouncycastle api for achieving the conversions without encoding issues. Built in crypto api can do the encryption/decryption for you.

Something like this:

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.apache.commons.codec.DecoderException;
import org.bouncycastle.util.encoders.Hex;

public class RC4Algo {

    public static void main(String args[])throws IOException, NoSuchAlgorithmException, DecoderException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException
    {
        decryptRC4();
    }

    static String decryptRC4() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException{

        byte[] plainBytes = "testString".getBytes();

        String hashedKey = hashedData("thisismysecretkey");

        //Generate a new key using KeyGenerator
        /*KeyGenerator rc4KeyGenerator = KeyGenerator.getInstance("RC4");
        SecretKey key = rc4KeyGenerator.generateKey();*/

        Key key = new SecretKeySpec(Hex.decode(hashedKey), "RC4"); //String to key conversion using Hex.decode to convert to byte []

        // Create Cipher instance and initialize it to encrytion mode
        Cipher cipher = Cipher.getInstance("RC4");  // Transformation of the algorithm
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] cipherBytes = cipher.doFinal(plainBytes);

        String encoded = encodeBase64(cipherBytes);

        String decoded = decodeBase64(encoded);

        // Reinitialize the Cipher to decryption mode
        cipher.init(Cipher.DECRYPT_MODE,key, cipher.getParameters());
        byte[] plainBytesDecrypted = cipher.doFinal(Hex.decode(decoded));

        System.out.println("Decrypted Data : "+new String(plainBytesDecrypted));
        return new String(plainBytesDecrypted);
    }

    static String decodeBase64(String encodedData){
        byte[] b = Base64.getDecoder().decode(encodedData);
        String decodedData = DatatypeConverter.printHexBinary(b);
        return decodedData;
    }

    static String encodeBase64(byte[] data){
        byte[] b = Base64.getEncoder().encode(data);
        String encodedData = new String(b);
        /*String encodedData = DatatypeConverter.printHexBinary(b);*/
        return encodedData;
    }

    static String hashedData(String key) throws NoSuchAlgorithmException{
        String password = key;

        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(password.getBytes());

        byte byteData[] = md.digest();

        //convert the byte to hex format method 1
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < byteData.length; i++) {
         sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
        }

        //convert the byte to hex format method 2
        StringBuffer hexString = new StringBuffer();
        for (int i=0;i<byteData.length;i++) {
            String hex=Integer.toHexString(0xff & byteData[i]);
            if(hex.length()==1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }

    }

Tip: Use Hex to binary and vice versa conversions to get rid of encoding issues.

Output:

enter image description here

Hope this helps!

0

RC4 is a byte-oriented algorithm. Java characters are not bytes. But you can convert strings to and from byte arrays as needed. You're welcome to check out my implementation here.

For the conversion to a string with UTF-8 encoding:

new String(bytes, "UTF-8");

and to a byte array:

str.getBytes("UTF-8");

or use a CharsetEncoder if you're not using a simple encoding like UTF-8.

Patrick
  • 33,984
  • 10
  • 106
  • 126
Gene
  • 46,253
  • 4
  • 58
  • 96