joey rohan
joey rohan

Reputation: 3566

Encryption RC4 algorithm for integers

Basically I can successfully implement RC4 algorithm for Strings, which takes an Byte[] array for the key :

byte [] key = "AAAAA".getBytes("ASCII");

If I take clearText as String say "24" then the cipher text range is very high, say > 2000 . But for my algorithm, I need to restrict it to fewer range ~200.

So can I have better option for int's ?

This is what I am doing with Strings :

Encrypt Mode:

  byte [] key = "AAAAA".getBytes("ASCII");

  String clearText = "66";


  Cipher rc4 = Cipher.getInstance("RC4");
  SecretKeySpec rc4Key = new SecretKeySpec(key, "RC4");
  rc4.init(Cipher.ENCRYPT_MODE, rc4Key);
  byte [] cipherText = rc4.update(clearText.getBytes("ASCII"));

Check values:

      System.out.println("clear (ascii)        " + clearText);
      System.out.println("clear (hex)          " + DatatypeConverter.printHexBinary(clearText.getBytes("ASCII")));
      System.out.println("cipher (hex) is      " + DatatypeConverter.printHexBinary(cipherText));

- Can any trick be preformed on these types to get a lower int value?

Decrypt :

  Cipher rc4Decrypt = Cipher.getInstance("RC4");
  rc4Decrypt.init(Cipher.DECRYPT_MODE, rc4Key);
  byte [] clearText2 = rc4Decrypt.update(cipherText);

SSCCE :

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
public class MyArcFour
{

  public static void main(String args[])throws Exception
    {


      byte [] key = "AAAAA".getBytes("ASCII");

      String clearText = "66";


      Cipher rc4 = Cipher.getInstance("RC4");
      SecretKeySpec rc4Key = new SecretKeySpec(key, "RC4");
      rc4.init(Cipher.ENCRYPT_MODE, rc4Key);

      byte [] cipherText = rc4.update(clearText.getBytes("ASCII"));

      System.out.println("clear (ascii)        " + clearText);
      System.out.println("clear (hex)          " + DatatypeConverter.printHexBinary(clearText.getBytes("ASCII")));
      System.out.println("cipher (hex) is      " + DatatypeConverter.printHexBinary(cipherText));


      Cipher rc4Decrypt = Cipher.getInstance("RC4");
      rc4Decrypt.init(Cipher.DECRYPT_MODE, rc4Key);
      byte [] clearText2 = rc4Decrypt.update(cipherText);

      System.out.println("decrypted (clear) is " + new String(clearText2, "ASCII"));
   }
}

Upvotes: 0

Views: 5159

Answers (1)

i_turo
i_turo

Reputation: 2729

When using a stream cipher (as RC4 is) the length of the ciphertext will always equal the length of the plaintext.

That means when you encrypt an int (which has 4 bytes), you will always receive another int (4 bytes) as encrypted output. So theoretically when you encrypt 0 you could get as a result 220.
If you want a value in range 0 - 255 you can only encrypt a single byte.

Any good encryption algorithm must satisfy the property that when using the same encryption key k any distinct plaintext p must encrypt to a distinct ciphertext c.
This property is only achievable when size(output) >= size(input).

Why must that the be case?
Well, consider the following encryption function:

/* output = E(key, input); key = 123 */

i | o
======
1 | 17
2 | 13
3 | 17
4 | 125

Then when you have the ciphertext 17 and the key 123 there is no way to tell if the originally encrypted value was 1 or 3.

That means if you want to be able to non ambiguously decrypt the values afterwards, there is no way to decrease the size of the resulting ciphertext.

If decrypting is not necessary, you could always do output % some_number or use a hash function with desired output length.

Upvotes: 3

Related Questions