I'm playing with the El Gamal cryptosystem, and my goal is to be able to encipher and decipher long sequences of text. I have come up with a method that works for short sequences, but does not work for long sequences, and I cannot figure out why.
El Gamal requires the plaintext to be an integer. I have turned my string into a byte[] using the .getBytes() method for Strings, and then created a BigInteger out of the byte[]. After encryption/decryption, I turn the BigInteger into a byte[] using the .toByteArray() method for BigIntegers, and then create a new String object from the byte[].
This works perfectly when i call ElGamalEncipher with strings up to 129 characters. With 130 or more characters, the output produced is garbled.
Can someone suggest how to solve this issue? Is this an issue with my method of turning the string into a BigInteger? If so, is there a better way to turn my string of text into a BigInteger and back?
Below is my encipher/decipher code.
public static BigInteger[] ElGamalEncipher(String plaintext, BigInteger p, BigInteger g, BigInteger r) {
// returns a BigInteger[] cipherText
// cipherText[0] is c
// cipherText[1] is d
BigInteger[] cipherText = new BigInteger[2];
BigInteger pText = new BigInteger(plaintext.getBytes());
// 1: select a random integer k such that 1 <= k <= p-2
BigInteger k = new BigInteger(p.bitLength() - 2, sr);
// 2: Compute c = g^k(mod p)
BigInteger c = g.modPow(k, p);
// 3: Compute d= P*r^k = P(g^a)^k(mod p)
BigInteger d = pText.multiply(r.modPow(k, p)).mod(p);
// C =(c,d) is the ciphertext
cipherText[0] = c;
cipherText[1] = d;
return cipherText;
}
public static String ElGamalDecipher(BigInteger c, BigInteger d, BigInteger a, BigInteger p) {
//returns the plaintext enciphered as (c,d)
// 1: use the private key a to compute the least non-negative residue
// of an inverse of (c^a)' (mod p)
BigInteger z = c.modPow(a, p).modInverse(p);
BigInteger P = z.multiply(d).mod(p);
byte[] plainTextArray = P.toByteArray();
String output = null;
try {
output = new String(plainTextArray, "UTF8");
} catch (Exception e) {
}
return output;
}