• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 586
  • Last Modified:

Badpaddingexception while decrypting

hai all
               i am doing a project in secured data transmission using core java, socket programming and cryptography.my program works on client side and server side. My problem is that i could encrypt the text successfully but i couldn't decrypt. when i try to decrypt i am getting an exception 'BadPaddingException' which i couldn't solve. in generating the encryption or decryption code i used DES encryption algorithm provided by JCE. in the program i used i/o streams and swings. here i am giving the entire coding of my program. plz help me out to solve this

import java.io.*;
import java.awt.*;
import java.text.*;
import java.lang.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import javax.crypto.*;
import java.security.*;
import java.security.interfaces.*;
import java.util.*;
import com.sun.crypto.provider.SunJCE.*;
class server extends JFrame implements ActionListener,Runnable
{
      Thread t;
      JFileChooser fc;
      JTextField jtf;
      JTextArea data;
      JLabel title;
      JFrame f;
      JButton open,receive,send,exit,encrypt,decrypt;
      Socket s;
      ServerSocket ss;
      JComboBox jcb;
      PrintStream ps;
      InputStreamReader j;
      BufferedReader br;
      public server()
      {
        t=new Thread(this,"RECEIVE");
            System.out.println("child Thread:"+t);
            t.start();
            JPanel p1=new JPanel(new FlowLayout());
            JPanel p2=new JPanel(new FlowLayout());
            JPanel p3=new JPanel(new FlowLayout());
            jtf=new JTextField(15);
            data=new JTextArea(100,30);
            title=new JLabel("SERVER IP");
            String[] item={"192.168.3.189"};
            jcb=new JComboBox(item);
            open=new JButton("OPEN");
            send=new JButton("SEND");
            exit=new JButton("EXIT");
            encrypt=new JButton("ENCRYPT");
            decrypt=new JButton("DECRYPT");
            p1.add(title);
            p1.add(jtf);
            p1.add(jcb);
            p2.add(data);
            p3.add(open);
            p3.add(send);
            p3.add(encrypt);
            p3.add(decrypt);
            p3.add(exit);
            int v=ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS;
            int h=ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS;
            JScrollPane jsp=new JScrollPane(p2,v,h);
            jsp.setViewportView(data);
            getContentPane().add(p1,BorderLayout.NORTH);
            getContentPane().add(p2,BorderLayout.CENTER);
            getContentPane().add(p3,BorderLayout.SOUTH);
            getContentPane().add(jsp,BorderLayout.CENTER);
            open.addActionListener(this);
            send.addActionListener(this);
            encrypt.addActionListener(this);
            decrypt.addActionListener(this);
            exit.addActionListener(this);
            setSize(400,400);
            show();

      }
      public void run()
      {
            try
            {
                  if(ss==null)
                  {
                        ss=new ServerSocket(2018);
                        s=ss.accept();
                        ps=new PrintStream(s.getOutputStream(),true);
                        j=new InputStreamReader(s.getInputStream());
                        br=new BufferedReader(j);
                        System.out.println("socket created");
           }
           while(true)
           {
                     //data.setText(" ");
                     String s4;
                     while((s4=br.readLine())!=null&& !(s4.equals("eof")))
                           {
                                 System.out.println("inside while");
                                 data.append(s4);
                                 data.append("\n");
                          //System.out.println(s4);

                        }
                Thread.sleep(100);
               }
    }
             catch(Exception e)
             {
                   System.out.println("Exception"+e);
               }

       }

      public void actionPerformed(ActionEvent ae)
      {
            String msg=ae.getActionCommand();
            try
            {
              if(msg.equals("SEND"))
                  {
                        jtf.setText(msg);
                        String s3=data.getText();
                        ps.println(s3);
                        ps.println("eof");

                  }
              if(msg.equals("OPEN"))
                  {
                        System.out.println("inside open");
                        fc=new JFileChooser();
                        int get=fc.showOpenDialog(f);
                        File file=fc.getSelectedFile();
                        String s2=file.toString();
                        FileReader fr=new FileReader(s2);
                        BufferedReader ds=new BufferedReader(fr);
                        String s1="";
                        data.setText("");
                        while((s1=ds.readLine())!=null)
                        {
                              data.append(s1);
                              data.append("\n");
                        }
                        jtf.setText(msg);
                        System.out.println("open completed");

                  }

                  jtf.setText(msg);
        if(msg.equals("ENCRYPT"))
                  {
                        SecretKey key=KeyGenerator.getInstance("DES").generateKey();
                        Cipher ec=Cipher.getInstance("DES");
                        ec.init(Cipher.ENCRYPT_MODE,key);
                        String str=data.getText();
                        byte[] b1=str.getBytes("UTF8");
                        byte[] b2=ec.doFinal(b1);
                        String encodedString=new sun.misc.BASE64Encoder().encode(b2);
                        data.setText(encodedString);
                  }
            if(msg.equals("DECRYPT"))
                  {

                    SecretKey key=KeyGenerator.getInstance("DES").generateKey();
                              Cipher dc=Cipher.getInstance("DES");
                              dc.init(Cipher.DECRYPT_MODE,key);
                              String st=data.getText();
                              byte[] b3=new sun.misc.BASE64Decoder().decodeBuffer(st);
                    //System.out.println(b3);
                    byte[] b4=dc.doFinal(b3);
                              System.out.println("inside decrypt");
                              System.out.println(b4);
                              String ca=new String(b4,"UTF8");
                              System.out.println(ca);
                          data.setText(ca);
                  }

        if(msg.equals("EXIT"))
                  {
                        jtf.setText(msg);
                        ps.close();
                        s.close();
                        ss.close();
                        System.exit(0);
                  }

            }
            catch(FileNotFoundException e)
             {
                  System.out.println("File not found"+e);
             }
          catch(UnknownHostException e)
             {
               System.out.println("unknown host"+e);
             }
            catch(IOException e)
            {
              System.out.println("I/O Exception"+e);
          }
        catch(Exception e)
             {
                   e.printStackTrace();
                   System.out.println("Exception"+e);
             }

      }
}
public class ctserver
{
      public static void main(String args[])throws Exception
      {
            new server();
      }
}


0
utterlyinneed
Asked:
utterlyinneed
  • 5
  • 2
  • 2
  • +1
1 Solution
 
petmagdyCommented:
could u please post the error stack?
0
 
petmagdyCommented:
I mean the error stack trace
0
 
gnoonCommented:
The problem is that you aren't using the same key as encryption while decrypting, because <code> KeyGenerator.getInstance("DES").generateKey() </code> always returns a new random key.

Try to use this function for key generator

    /*
    * Creates a Key object for the specified key string.
    * @param keyString the string with its total length should be a multiple of 8 (DES)
    * @return the new Key object, null if any exception occurs.
    * @author G noon
    */
    private Key getKey(String keyString)
    {
        try
        {
            byte[] bytes = getbytes(KEYGEN_STR);
            DESKeySpec pass = new DESKeySpec(bytes);

            SecretKeyFactory sKeyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey sKey = sKeyFactory.generateSecret(pass);

            return sKey;
        }
        catch(Exception ex)
        {
            return null;
        }
    }

Then, gets the key for encryption and decryption processes, for example

    SecretKey key = getKey("12345678");

G noon
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

 
gnoonCommented:
Sorry type mistakenly. The function should be

   /*
    * Creates a Key object for the specified key string.
    * @param keyString the string with its total length should be a multiple of 8 (DES)
    * @return the new Key object, null if any exception occurs.
    * @author G noon
    */
    private Key getKey(String keyString)
    {
        try
        {
            byte[] bytes = keyString.getBytes("UTF-8");
            DESKeySpec pass = new DESKeySpec(bytes);

            SecretKeyFactory sKeyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey sKey = sKeyFactory.generateSecret(pass);

            return sKey;
        }
        catch(Exception ex)
        {
            return null;
        }
    }

and then, gets the key

   SecretKey key = (SecretKey) getKey("12345678"); //<------- casting forgotten ;-)

G noon
0
 
gnoonCommented:
Also, you need to import javax.crypto.spec.DESKeySpec.
0
 
utterlyinneedAuthor Commented:
hai gnoon
                   in the codings you have given i don't understand this one
 SecretKey key = (SecretKey) getKey("12345678"); //<------- casting forgotten ;-)
 
from where the value of key is obtained and what is "12345678" represents? when i use ur codings in my program which i posted earlier i am getting 4 error messages i am quoting that also here

illegal start of expression at
private Key getKey(String KeyString)
cannot resolve symbol at
ec.init(Cipher.ENCRYPT_MODE,key);

please consider this soon and give me a correct answer it is urgent please
0
 
gnoonCommented:
>in the codings you have given i don't understand this one
>SecretKey key = (SecretKey) getKey("12345678"); //<------- casting forgotten ;-)

I provided you how to call the getKey() function I posted above. The trail end comment: I just told you that I typed mistakenly in the first time.

>what is "12345678" represents?

It's a secret key string. A secret key string is used to construct a SecretKey object for encryption/decryption.
I used "12345678" because I want to show you that a secret key string should be with total length a multiple of 8.

However, you can write your own function to generates a random secret key string for encryption/decryption.

I'll give you an example, here

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import java.security.*;

/*
 * DES.java 3/11/2004 14:41
 *
 * Encrypts and decrypts a string with DES algorithm.
 * @author G noon
 */

public class DES
{
    public static final String DEFAULT_KEYSTRING = "!#%&(_+)"; // 64 bits

    /*
     * Generates a random secret key string for DES encryption.
     * @return the secret key string
     */
    public String getSessionKeyString()
    {
        try
        {
            return new String(KeyGenerator.getInstance("DES").generateKey().getEncoded());
        }
        catch(NoSuchAlgorithmException ex)
        {
            return DEFAULT_KEYSTRING;
        }
    }

    /*
    * Creates a Key object for the specified key string.
    * @param keyString the string with its total length should be a multiple of 8 (DES)
    * @return the new Key object, null if any exception occurs.
    */
    private Key getKey(String keyString)
    {
        try
        {
            byte[] bytes = keyString.getBytes("UTF-8");
            DESKeySpec pass = new DESKeySpec(bytes);

            SecretKeyFactory sKeyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey sKey = sKeyFactory.generateSecret(pass);

            return sKey;
        }
        catch(Exception ex)
        {
            return null;
        }
    }

    /*
     * Encrypts the specified string with the specified key string by DES algorithm.
     * @param text the specified string
     * @param keyString the specified key string
     * @return the encrypted string in base64 format
     * @exception java.lang.Exception if any error occurs
     */
    public String encrypt(String text, String keyString) throws Exception
    {
        SecretKey key=(SecretKey)getKey(keyString);
        Cipher ec=Cipher.getInstance("DES");
        ec.init(Cipher.ENCRYPT_MODE,key);
        byte[] b1=text.getBytes("UTF8");
        byte[] b2=ec.doFinal(b1);
        return new sun.misc.BASE64Encoder().encode(b2);
    }

    /*
     * Decrypts the specified string with the specified key string by DES algorithm.
     * @param text the specified string
     * @param keyString the specified key string
     * @return the decrypted string in utf-8 encoding
     * @exception java.lang.Exception if any error occurs
     */
    public String decrypt(String encoded, String keyString) throws Exception
    {
        SecretKey key=(SecretKey)getKey(keyString);
        Cipher dc=Cipher.getInstance("DES");
        dc.init(Cipher.DECRYPT_MODE,key);
        byte[] b3=new sun.misc.BASE64Decoder().decodeBuffer(encoded);
        byte[] b4=dc.doFinal(b3);
        return new String(b4,"UTF8");
    }

    /*
     * TODO
     */
    public static void main(String[] args) throws Exception
    {
        DES des = new DES();

        String mySecret = "I'm not a man, not a woman!";
        String mySecretKey = des.getSessionKeyString();

        String myEncrypted = des.encrypt(mySecret, mySecretKey);
        String myDecrypted = des.decrypt(myEncrypted, mySecretKey);

        System.out.println("My secret: "+mySecret);
        System.out.println("My secret key: "+mySecretKey);
        System.out.println("After encrypted: "+myEncrypted);
        System.out.println("After decrypted: "+myDecrypted);
    }

}

0
 
utterlyinneedAuthor Commented:
hai gnoon
               thanks for th help you are giving. the code you have given works well as such(ie in console environment) but it is showing bad padding exception in the client server environment where data is encrypted at the server side and decrypted at the client side. i tried every possible altenatives to resolve the problem but couldn't find a positive result. can u plz show me how the code can be implemented to a client server environment without bad padding exception.plz give a solution.

Thanks
0
 
gnoonCommented:
/*** server.java ***/
import java.io.*;
import java.net.*;

public class server
{
    final int port = 2018;
    final String defaultKey = "87654321";
    final DES des = new DES();

    ServerSocket service;

    public void listen() throws Exception
    {
        service = new ServerSocket(port);
        System.out.println("Listen on port "+port);
        Socket socket = service.accept();
        System.out.println(socket.getInetAddress()+" connected.");

        PrintStream out = new PrintStream(socket.getOutputStream());
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        String data = in.readLine();
        String decrypted = des.decrypt(data,defaultKey);
        System.out.println("I got '"+decrypted+"' from "+socket.getInetAddress());
        out.println(des.encrypt(decrypted, defaultKey)); // send data

        out.close();
        in.close();
        socket.close();
    }

    public static void main(String[] args) throws Exception
    {
        new server().listen();
    }
}

/*** client.java ***/

import java.io.*;
import java.net.*;

public class client
{
    final String server = "127.0.0.1";
    final int port = 2018;
    final String defaultKey = "87654321";
    final DES des = new DES();

    Socket socket;

    public String echo(String data) throws Exception
    {
        String response = null;
        socket = new Socket(server, port);
        PrintStream out = new PrintStream(socket.getOutputStream());
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        out.println(des.encrypt(data,defaultKey)); // send data
        response = in.readLine();               // get response

        out.close();
        in.close();
        socket.close();

        return des.decrypt(response,defaultKey);
    }

    public static void main(String[] args) throws Exception
    {
        System.out.print("Enter a string: ");
        String data = new BufferedReader(new InputStreamReader(System.in)).readLine();
        String response = new client().echo(data);
        System.out.println("Response from server: "+response);
    }
}

The point is the key used to decrypt at client must be *the same* as the key used to encrypt at server.
I used "87654321" as the key in the code above.

G noon
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

  • 5
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now