Solved

AES Cipher javax.crypto.IllegalBlockSizeException

Posted on 2011-09-14
5
3,148 Views
Last Modified: 2012-05-12
Hello,

I have the following code which I am using to decode a base64encoded string which was encoded also using an AES cipher.

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.*;

public class EncryptionHelper {
      private String algorithm = "AES";
      private SecretKeySpec  keySpec = null;
      private byte[] key = "Wydopqswrlmesf==".getBytes();

      private Cipher cipher = null;
      
      public EncryptionHelper() throws NoSuchAlgorithmException, NoSuchPaddingException{      
            cipher = Cipher.getInstance(algorithm);
            keySpec = new SecretKeySpec(key, algorithm);
      }
      

      
      public String decrypt(String passphrase) throws InvalidKeyException,BadPaddingException, IllegalBlockSizeException, IOException {
                        
            byte[] encryptionBytes = org.apache.commons.codec.binary.Base64.decodeBase64(passphrase);
            
            cipher.init(Cipher.DECRYPT_MODE, keySpec);                        
            
            byte[] recoveredBytes = cipher.doFinal(encryptionBytes);
            
            String recovered = new String(recoveredBytes);                        

            return recovered;
      }


}

I receive an error though as follows

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
      at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
      at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
      at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
      at javax.crypto.Cipher.doFinal(DashoA13*..)
      at com.avaya.utility.updater.EncryptionHelper.decrypt(EncryptionHelper.java:56)
      at com.avaya.utility.updater.Controller.main(Controller.java:92)

The key I've provided in "private byte[] key = "Wydopqswrlmesf==".getBytes();" is just a sample key I've added in this post, not the actual key.

Can any of you see where my errors may be occuring? the string I pass in is 16 characters in length.

Thanks in advance.
0
Comment
Question by:speedygonzalez
  • 2
  • 2
5 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 36536170
Please post the output of the following
System.out.printf("The length of the buffer to be decrypted is %d bytes\", encryptionBytes.length);

Open in new window

0
 

Expert Comment

by:BlnGuy
ID: 36536354
Your input data must have a length which is a multiple of 8. If you try to encode a text that is, e.g. 12 bytes long, you will get this error. Before you can encrypt your text properly make sure its length is a multiple of 8.

If you don't want to do padding yourself, you may use another encryption provider, like "Blowfish/CBC/PKCS5Padding" instead of "AES".
0
 

Author Comment

by:speedygonzalez
ID: 36954991
Hi All,  Apologies, I've been off the radar the past few weeks.

On printing out the bytes the following error occurs.

EncryptionHelper.encrypt...byte array length: 18EncryptionHelper.encrypt...string interpretation: [B@b179c3 Encrypt len = 44 EncryptionHelper.encrypt...return value: [B@67ac19 String decoded = [B@53ba3d Lent=5 testt Controller.main...exception, illegal block size: javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.avaya.utility.updater.EncryptionHelper.decrypt(EncryptionHelper.java:60)
at com.avaya.utility.updater.Controller.main(Controller.java:90)


My full class is as follows (you can ignore the actual "key" as I've just made it up for posting here).

Any help is appreciated.  Thanks.


    package com.avaya.utility.updater;  
     
    import java.io.IOException;  
    import java.security.InvalidKeyException;  
    import java.security.NoSuchAlgorithmException;  
     
    import javax.crypto.BadPaddingException;  
    import javax.crypto.Cipher;  
    import javax.crypto.IllegalBlockSizeException;  
    import javax.crypto.NoSuchPaddingException;  
    import javax.crypto.spec.SecretKeySpec;  
    import org.apache.commons.codec.binary.*;  
     
    public class EncryptionHelper {  
        private String algorithm = "AES";  
        private SecretKeySpec  keySpec = null;  
        private byte[] key = "Wydopqswrlmesf==".getBytes();
     
        private Cipher cipher = null;  
         
        public EncryptionHelper() throws NoSuchAlgorithmException, NoSuchPaddingException{    
            cipher = Cipher.getInstance(algorithm);  
            keySpec = new SecretKeySpec(key, algorithm);  
        }  
     
        public String encrypt(String input) throws InvalidKeyException, BadPaddingException,IllegalBlockSizeException {      
             
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);  
             
            byte[] inputBytes = input.getBytes();  
            System.out.print("EncryptionHelper.encrypt...byte array length: " + inputBytes.length);  
             
            String returnVal = inputBytes.toString();        
            System.out.print("EncryptionHelper.encrypt...string interpretation: " + returnVal);  
             
            //return new sun.misc.BASE64Encoder().encode(cipher.doFinal(inputBytes));  
             
            byte[] finalResult = input.getBytes();        
            finalResult =org.apache.commons.codec.binary.Base64.encodeBase64(cipher.doFinal(inputBytes));  
             
            System.out.print(" Encrypt len = " + finalResult.length + " ");      
                     
            String encryptedStr = finalResult.toString();  
            System.out.print("EncryptionHelper.encrypt...return value: " + encryptedStr);  
             
            return encryptedStr;  
             
            //return new org.apache.commons.codec.binary.encodeBase64(cipher.doFinal(inputBytes));        
        }  
     
         
        public String decrypt(String passphrase) throws InvalidKeyException,BadPaddingException, IllegalBlockSizeException, IOException {  
                 
            byte[] passPhraseBytes = passphrase.getBytes();          
                byte[] encryptionBytes = org.apache.commons.codec.binary.Base64.decodeBase64(passPhraseBytes);  
            System.out.print(" String decoded = " + encryptionBytes.toString() + " ");                
            System.out.print("Lent=" + encryptionBytes.length + " ");  
            cipher.init(Cipher.DECRYPT_MODE, keySpec);  
            System.out.print(" testt  ");        
            byte[] recoveredBytes = cipher.doFinal(encryptionBytes);  
            System.out.print(" testt 2 ");            
            String recovered = new String(recoveredBytes);  
     
            System.out.print("EncryptionHelper.decrypt...return value: " + recovered);  
     
            return recovered;  
        }  
    }  

0
 
LVL 86

Accepted Solution

by:
CEHJ earned 500 total points
ID: 36955317
You have logical errors in your encrypt method. Should be
public String encrypt(String input)
        throws InvalidKeyException, BadPaddingException,
            IllegalBlockSizeException {
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);

        byte[] inputBytes = input.getBytes();
        System.out.print("EncryptionHelper.encrypt...byte array length: " + inputBytes.length);

        String returnVal = inputBytes.toString();
        System.out.print("EncryptionHelper.encrypt...string interpretation: " + returnVal);

        byte[] finalResult = org.apache.commons.codec.binary.Base64.encodeBase64(cipher.doFinal(inputBytes));

        System.out.println(" Encrypt len = " + finalResult.length + " ");

        String encryptedStr = new String(finalResult);
        System.out.println("EncryptionHelper.encrypt...return value: " + encryptedStr);

        return encryptedStr;

    }

Open in new window

0
 

Author Closing Comment

by:speedygonzalez
ID: 36955553
Thanks. Excellent Help!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now