title: Java Cipher padding Error
body: <p>I am new to java and trying to encrypt and decrypt two text messages using <code>Cipher</code> and <code>SecretKey</code> as shown in the code bellow(Line 241, at the very bottom). Whenever I tries to <code>Decrypt</code> this encrypted message, I get an error saying:<br>
  <code>javax.crypto.BadPaddingException: Given final block not properly padded</code>
  <code>javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher</code><br>
  I am using 3 Threads in this code and two buffers/queues called q1 and q2. At first, I put a message in a buffer/queue. Then in the next class, I retrieve that message and encrypt it, and send to the next class. Then that class will put it in a buffer/queue again. Finally, at the last class, it will retrieve from the buffer and decrypt it. This is where the problem happens. There is a Synchronization error going on. I have been trying to figure this error for many days now and no luck. Other online documentations didn't help either. I would greatly appreciate if you could edit this code or show me with an example </p>
  
  <pre><code>import java.security.KeyPairGenerator;
  import java.security.KeyPair;
  import java.security.NoSuchAlgorithmException;
  import java.security.PublicKey;
  import java.security.PrivateKey;
  import java.security.Signature;
  import java.io.*;
  import java.util.*;
  import java.util.concurrent.TimeUnit;
  import javax.crypto.Cipher;
  import javax.crypto.KeyGenerator;
  import javax.crypto.NoSuchPaddingException;
  import javax.crypto.SecretKey;
  
  
  
  class Q5 { //Queue/Buffer   
      byte[] shipmentConfirmation;//will include the actual message content been delivered
      boolean valueSet = false;
      synchronized byte[] get() 
      {       
          while(!valueSet) 
          try 
          {
              wait();
          } 
          catch(InterruptedException e) 
          {
              System.out.println("InterruptedException caught");
          }
          //System.out.println("Got: " + n);
          valueSet = false;
          notify();
          return shipmentConfirmation;
      }
      synchronized void put(byte[] shipmentCinfirm) 
      {
          while(valueSet)
          try 
          {
              wait();
          } 
          catch(InterruptedException e) 
          {
              System.out.println("InterruptedException caught");
          }
          this.shipmentConfirmation = shipmentCinfirm;
          valueSet = true;
          //System.out.println("Put: " + n);
          notify();
      }
  }
  
  class Global5{
      public static int sendcouter = 0;
      public static SecretKey secret_Key;
      public static Cipher desCipher;
  }
  
  
  //&lt;&lt;security pattern&gt;&gt; SymmetricEncryptionEncryptor
  class SecurityEncryptor//&lt;&lt;security&gt;&gt; Encryptor
  {
      static byte[] Encryptor(byte shipmentConfirmation[],Cipher c) throws Exception //Encryptor
      {       
          byte[] ciphertext = SecurityEncryptionAlgorithm.EncryptionAlgorithm(shipmentConfirmation,c,Global5.secret_Key);
          return ciphertext;
      }   
  }
  class SecurityEncryptionAlgorithm//&lt;&lt;security&gt;&gt; EncryptionAlgorithm
  {
      static byte[] EncryptionAlgorithm(byte shipmentConfirmation[],Cipher c,SecretKey sk) throws Exception 
      {
          c.init(Cipher.ENCRYPT_MODE, sk);
          return c.doFinal(shipmentConfirmation);
      }
  }
  
  
  
  //&lt;&lt;security pattern&gt;&gt; aSecureAsynchronousMCReceiverConnector
  class SecurityDecryptor//&lt;&lt;Security&gt;&gt; Decryptor
  {
      static byte[] Decryptor(byte EncryptedShipmentConfirmation[],Cipher c,SecretKey sk) throws Exception //Decryptor
      {
          byte[] ct = SecurityDecryptionAlgorithm.DecryptionAlgorithm(EncryptedShipmentConfirmation,c,sk);
          return ct;
      }   
  }
  class SecurityDecryptionAlgorithm//&lt;&lt;Security&gt;&gt; DecryptionAlgorithm
  {
      static byte[] DecryptionAlgorithm(byte EncryptedShipmentConfirmation[],Cipher c,SecretKey sk) throws Exception 
      {
          c.init(Cipher.DECRYPT_MODE, sk);
          return c.doFinal(EncryptedShipmentConfirmation);
      }
  }
  
  
  
  public class testFigure1 { //Main
         public static void main(String args[]) throws Exception {          
              Q5 q1 = new Q5();//creating buffer/queue
              Q5 q2 = new Q5();
  
              System.out.println("How many messages to send: ");
              Scanner in = new Scanner(System.in);
              int input = in.nextInt();//Get input from the supplier          
  
              aSupplierInterface Supplier = new aSupplierInterface(q1, input);    
              aSecuritySenderCoordinator SenderCoordinator = new aSecuritySenderCoordinator(q1, input, q2);           
              aSecurityReceiverCoordinator receive = new aSecurityReceiverCoordinator(q2, input);   
              Supplier.t_pro.join();
              SenderCoordinator.t_coordinator5.join();
              receive.t_SecurityReceiverCoordinator5.join();
              System.out.println("End of Program!");
         }   
  }
  
  class aSupplierInterface  implements Runnable //&lt;&lt;application Component&gt;&gt; aSupplierInterface
  {
      Q5 q;   
      int supinput;
      Thread t_pro;//pro to represent producer or suppler
      aSupplierInterface(Q5 qq, int input)
      {
          supinput = input;
          this.q = qq;
          t_pro = new Thread(this, "Producer");
          t_pro.start();
      }
      public void run() 
      {
          int i = 0;
          String shipment;
          byte[] shipmentConfirmation;
          while(i&lt;supinput)
          {
              i++;
              shipment = "This is the Delivery Number: "+ i;
              shipmentConfirmation = shipment.getBytes();
  
              q.put(shipmentConfirmation);//Putting supplier's goods in a queue/buffer            
          }   
      }       
  }
  
  class aSecuritySenderCoordinator implements Runnable //&lt;&lt;security coordinator&gt;&gt; aSecuritySenderCoordinator
  {
      Q5 q;
      Q5 q2;
      Thread t_coordinator5;
      int supinput;
  
      public aSecuritySenderCoordinator(Q5 qq, int input, Q5 q2) throws Exception
      {       
          supinput=input;
          this.q = qq;    
          this.q2=q2;
          t_coordinator5 = new Thread(this, "coordinator5");
          t_coordinator5.start();
      }
  
      public void run() 
      {
          byte[] pkShipmentConfirmation;
          byte[] shipmentConfirmation;
          int i = 0;
          while(i&lt;supinput) 
          {               
              i++;
  
                  //Getting goods that supplier has put in the queue previously
              pkShipmentConfirmation=q.get();//This will contain content of the message/delivery you are sending
              KeyGenerator keygen;
              try {
              keygen = KeyGenerator.getInstance("DES");
              Global5.sendcouter++;//To Create the key once
              if(Global5.sendcouter==1)//Create once
              {
                  Global5.secret_Key = keygen.generateKey();
                  Global5.desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
              }           
              //String st1 = new String(pkShipmentConfirmation);//just to print a message
              //System.out.println("*ORIGINAL MESSAGE:"+st1);    
              shipmentConfirmation = SecurityEncryptor.Encryptor(pkShipmentConfirmation,Global5.desCipher);//Encrypting 
  
  
              new anAsynchronousMCReceiver(q2, shipmentConfirmation);     
  
              } catch (NoSuchAlgorithmException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
          }
      }
  }
  
  
  
  
  class anAsynchronousMCReceiver 
  { //&lt;&lt;communication pattern&gt;&gt; anAsynchronousMCReceiver
         Q5 q;
  
         anAsynchronousMCReceiver( Q5 q2, byte[] shipmentConfirm) throws Exception
         {
             this.q = q2;
             q.put(shipmentConfirm);  //Entering received data in to the Queue/Buffer 
         }
  }
  
  
  
  class aSecurityReceiverCoordinator implements Runnable//&lt;&lt;security coordinator&gt;&gt; aSecurityReceiverCoordinator
  {       
      Thread t_SecurityReceiverCoordinator5;  
      Q5 q;
      int supinput;
      byte[]encryptedShipmentConfirmation;
      public aSecurityReceiverCoordinator(Q5 q2, int input) throws Exception
      {  
          this.q = q2;    
          supinput = input;
          t_SecurityReceiverCoordinator5 = new Thread(this, "SecurityReceiverCoordinator5");
          t_SecurityReceiverCoordinator5.start();
  
      }
      public void run() 
      {
          try {
              int i = 0;
              while(i&lt;supinput) 
              {           
                  i++;
                  encryptedShipmentConfirmation = q.get();                
                  byte[] confirmation = SecurityDecryptor.Decryptor(encryptedShipmentConfirmation,Global5.desCipher,Global5.secret_Key);//ERROR HAPPENS HERE              
                  String shipConfirmation = new String(confirmation);
  
                  System.out.println("AT DelivertyOrder: " +  shipConfirmation);
              }
          } catch (Exception e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>If you copy and past this program, it will run on your computer</p>