Problems with encoding in RC4 Algorithm

189 Views Asked by At

I have to make a small demonstration about encrypting text using the RC4 Algorithm. To do so, I chose to use Java in NetBeans.

My code uses byte arrays for the permutation and the XOR operation. But the input and the output are to be in String.

  1. Almost all of my outputs, for encryption looks like this: "¯[á" . Is it normal? Using this however, i can still find the plain text, which in this case is "though".
  2. let's say I am trying to encrypt the word "stack". The result I would sometimes get would be of form: "¯[??ô" and then while trying to decrypt, I will get: "s??ck" or "stÄck". This especially happens if my key and the origin plain text is in french (which sucks since it's the language I a making the presentation in).

I tried changing the encoding character, from UTF-8, to ISO-8859-1 to ASCII. I have had the best results with ASCII. It gives me less question marks, but is sometimes changes the characters.

  1. This is an example of strange character returns
  2. Same code. Just changed the print sentences in french, and used french words for encryption, but there is a question mark

My RC4 class code for encrypting and decrypting text

public class RC4 
{
    private int[] S =new int[256];
    private int[] T =new int[256];
    private int keylen;
    
    public RC4(byte[] key)
    {
        if (key.length < 1 || key.length > 256) {
            throw new IllegalArgumentException("La clé doit avoir entre 1 et 256 bytes");
        }
        else
        {
            keylen = key.length;
            for (int i = 0; i < 256; i++) //initialisation de S et T 
            {
                S[i] = i;
                T[i] = (int)key[i % keylen];
            }
            int j = 0;
            for (int i = 0; i < 256; i++) //Premiere permutation de S qui utilise la clé
            {
                j = (j + S[i] + T[i]) % 256;
                int temp = S[i];
                S[i] = S[j];
                S[j] = temp;
            }
        }
    }
    
    public byte[] chiffrer(byte[] plaintext) 
    {
        int i = 0;
        int j = 0;
        byte[] ciphertext = new byte[plaintext.length];// texte et cryptogramme ont la même longueur 
        for (int k = 0; k < plaintext.length; k++) //seconde permutation, n'utilisant que des procédés mathématiques sans l'intervention de la clé
        {
            i = (i + 1) % 256;
            j = (j + S[i]) % 256;
            int temp = S[i];
            S[i] = S[j];
            S[j] = temp;
            int t = (S[i] + S[j]) % 256;
            int keystream = S[t];
            byte keyByte = (byte)keystream;
            ciphertext[k] = (byte)(plaintext[k] ^ keyByte ); //Pour l'opération XOR  
        }
        
        return ciphertext;
    }
    
    public byte[] dechiffrer(byte[] ciphertext) 
    {
        return chiffrer(ciphertext); // Le chiffrement et le déchiffrement se font exactement de la même manière
    }
}

My main class

public class testRC4 
{

    public static void main(String args[])
    {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Saisir la clé secrète:");
        String keyText = scanner.nextLine();
        byte[] key = keyText.getBytes();
        RC4 rc = new RC4(key);
        System.out.println("Entrer a pour chiffrer et b pour déchiffrer:");
        String choice = scanner.nextLine();
        if (choice.equals("a"))
        {
            System.out.println("Saisir le mot à chiffrer:");
            String plainText = scanner.nextLine();
            byte[] plain = plainText.getBytes();   
            byte[] cipher = rc.chiffrer(plain);
            String cipherText = new String(cipher);
            System.out.println("Le cryptogramme :  " +cipherText);  
        }
        else if(choice.equals("b"))
        {
            System.out.println("Saisir le mot à déchiffrer :");
            String cipherText = scanner.nextLine();
            byte[] cipher = cipherText.getBytes();
            byte[] plain = rc.chiffrer(cipher);
            String plainText = new String(plain);
            System.out.println("Le texte en clair :  " +plainText);     
        }
        else
        {
            System.out.println("Le choix fait n'est pas reconnu. Veuillez recommencer!");
        }
        
    }
}
1

There are 1 best solutions below

0
teapot418 On

Diagnosed in comments. The main problem is that the ciphertext contains hairy unprintable characters that break when copy&pasted.

Recommeded solution: display ciphertext in hexadecimal instead.