Skip to Main Content

Java Security

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

key exchange in rsa work but not in elgamal, throw invalidkeyexception

843811Jan 26 2010 — edited Jan 26 2010
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.
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Feb 23 2010
Added on Jan 26 2010
1 comment
466 views