I'm playing with the El Gamal cryptosystem, and my goal is to be able to encipher and decipher long sequences of text.
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[].
I am using a 1035 bit key, and this works perfectly when I encipher/decipher with strings up to 129 characters. With 130 or more characters, the output produced from my decipher method is garbled.
Can someone suggest how to solve this issue?
Just like in RSA, you cannot encrypt a value larger than the modulus in ElGamal.
You can try
BigInteger pText = new BigInteger(plaintext.getBytes("UTF-8"));
to make the encoding/decoding and enciphering/deciphering more symmetric, but I'm not sure if that's the root cause.
By the way, you should never silently consume an Exception
. The very least you can do is just catch (UnsupportedEncodingException e)
.
You need to use positive numbers for your operations. So you must construct BigInteger like this,
BigInteger pText = new BigInteger(1, plaintext.getBytes());
// 1: select a random integer k such that 1 <= k <= p-2
BigInteger k = abs(new BigInteger(p.bitLength() - 2, sr));
If you want to encrypt certain data with asymmetric cryptographic algorithm, you can do this only for really short data block. The reasons are both "technical" (the algorithm works this way) and "practical" (asymmetric cryptography is slow).
The right way to encrypt the large block of data using asymmetric cryptographic algorithm is
- generate random ("session") key for some symmetric algorithm (AES, RC4, 3DES, you name it).
- use this algorithm to encrypt the data
- use your asymmetric algorithm to encrypt the session key
- store the encrypted key near the data.
- stop reinventing the wheel