Hi, I'm learning cryptography now. So i'm pretty much new to it. I changed source code from "beginning cryptography with java" about key exchange and added a digest. It was originally for rsa but the book says it can be used on elgamal too. But when i tried with elgamal it throws this exception
"input : I love you forever
keyBlock length : 256
input length : 18
cipherText : °¼?ÜÖ®u!¢[:Í?î\ó@º¸7æóýµ60?H#·Ø3eª;
cipherText length: 38
java.security.InvalidKeyException: Key length not 128/192/256 bits.
at org.bouncycastle.jce.provider.JCEBlockCipher.engineInit(Unknown Source)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at chapter4.ElGamalwDigestSecureRandom.main(ElGamalwDigestSecureRandom.java:104)"
My guess is on the decryption step. I wonder where did i go wrong? I searched documentations and publications but still couldn't find what it was. What can i say, guess i'm a noob. Can you help me point my mistake for the exception above?
Here is the code for two classes i used, utils(i merged the utils class just for this forum, since there are three of them) and main(sorry it really is a mess):
package chapter4;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* RSA example with OAEP Padding and random key generation.
*/
public class ElGamalwDigestSecureRandom
{
private static byte[] packKeyAndIv(
Key key,
IvParameterSpec ivSpec)
throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
bOut.write(ivSpec.getIV());
bOut.write(key.getEncoded());
return bOut.toByteArray();
}
private static Object[] unpackKeyAndIV(
byte[] data)
{
byte[] keyD = new byte[16];
byte[] iv = new byte[data.length - 16];
return new Object[] {
new SecretKeySpec(data, 16, data.length - 16, "AES"),
new IvParameterSpec(data, 0, 16)
};
}
public static void main(
String[] args)
throws Exception
{
String input = "I love you forever";
SecureRandom random = new SecureRandom();
// create the ElGamal Key
KeyPairGenerator generator = KeyPairGenerator.getInstance("ElGamal", "BC");
generator.initialize(1024, random);
KeyPair pair = generator.generateKeyPair();
Key pubKey = pair.getPublic();
Key privKey = pair.getPrivate();
// add digest
MessageDigest hash = MessageDigest.getInstance("SHA-1", "BC");
System.out.println("input : " + input);
// create the symmetric key and iv
Key sKey = Utils.createKeyForAES(256, random);
IvParameterSpec sIvSpec = Utils.createCtrIvForAES(0, random);
// symmetric key/iv wrapping step
Cipher xCipher = Cipher.getInstance("ElGamal/NONE/NoPadding", "BC");
xCipher.init(Cipher.ENCRYPT_MODE, pubKey, random);
byte[] keyBlock = xCipher.doFinal(packKeyAndIv(sKey, sIvSpec));
// encryption step
Cipher sCipher = Cipher.getInstance("AES/CTR/NoPadding", "BC");
sCipher.init(Cipher.ENCRYPT_MODE, sKey, sIvSpec);
// append digest
byte[] cipherText = new byte[sCipher.getOutputSize(input.length() + hash.getDigestLength())];
int ctLength = sCipher.update(Utils.toByteArray(input), 0, input.length(), cipherText, 0);
hash.update(Utils.toByteArray(input));
ctLength += sCipher.doFinal(hash.digest(), 0, hash.getDigestLength(), cipherText, ctLength);
System.out.println("keyBlock length : " + keyBlock.length);
System.out.println("input length : " + input.length());
System.out.println("cipherText : " + Utils.toString(cipherText));
System.out.println("cipherText length: " + cipherText.length);
// symmetric key/iv unwrapping step
xCipher.init(Cipher.DECRYPT_MODE, privKey);
Object[] keyIv = unpackKeyAndIV(xCipher.doFinal(keyBlock));
// decryption step
sCipher.init(Cipher.DECRYPT_MODE, (Key)keyIv[0], (IvParameterSpec)keyIv[1]);
//digest check
byte[] plainText = sCipher.doFinal(cipherText, 0, ctLength);
int messageLength = plainText.length - hash.getDigestLength();
hash.update(plainText, 0, messageLength);
byte[] messageHash = new byte[hash.getDigestLength()];
System.arraycopy(plainText, messageLength, messageHash, 0, messageHash.length);
System.out.println("DigestLength : " + hash.getDigestLength());
System.out.println("plain : " + Utils.toString(plainText, messageLength) + " verified: " + MessageDigest.isEqual(hash.digest(), messageHash));
}
}
Thank you.