如何解决不良填充问题

时间:2013-01-28 06:29:01

标签: java encryption rsa padding

我正在尝试在服务器和客户端之间创建RSA加密聊天程序。但是当我收到并尝试解密消息时,我遇到了一个错误的填充异常。这是我的代码。

请帮帮我!非常感谢您的帮助!

客户端:

Socket s;
BufferedReader br;
BufferedWriter bw;
TextField text;
Button sendBut, exitBut;
List list;

public client(String st)
{
  super(st);
  setSize(300, 130);

  setLocation(300,0);
  setResizable(true);
  setBackground(new Color(192, 192, 192));
  this.setLayout(new GridLayout(2, 1));

  Panel panels[] = new Panel[2];
  panels[0] = new Panel();
  panels[1] = new Panel();
  panels[0].setLayout(new BorderLayout());
  panels[1].setLayout(new FlowLayout(FlowLayout.LEFT));

  sendBut = new Button("Send");
  exitBut = new Button("Exit");

  sendBut.addActionListener(this);
  exitBut.addActionListener(this);

  list = new List();
  text = new TextField(25);

  panels[0].add(list);
  panels[1].add(text);
  panels[1].add(sendBut);
  panels[1].add(exitBut);     


  add(panels[0]);
  add(panels[1]);

  setVisible(true);

  try
  {
    /* Assuming that this application is run on single
                      machine I've used the default ip i.e., 127.0.0.1. If
                      you want to use it on 2 different machines use the
                      ip that is assigned to the machine on which server
                      applicatin is residing*/

    s = new Socket("127.0.0.1", 1053);
    br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
    Thread th;
    th = new Thread(this);
    th.start();

  }catch(Exception e){}

}

public static void main(String arg[])
{
  // create an object instance of the class
  // by sending the title as parameter
  new client("Client Application");

}

public void run()
{
  while (true)
  {
    try
    {
      String receive = br.readLine();
      list.addItem(receive);
      byte[] msg1 = receive.getBytes("UTF-8");
      //decrypt
      //Get pri Key
      FileInputStream FISkey1 = new FileInputStream("privatekey.txt");
      ObjectInput oi1 = new ObjectInputStream(FISkey1);  
      Key privateKey = (Key) oi1.readObject(); 
      FISkey1.close();
      Cipher cipher1 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
      //encrypt the public key
      cipher1.init(Cipher.DECRYPT_MODE, privateKey);
      byte[] deciphertext = cipher1.doFinal(msg1);
      String receivePrint = new String(deciphertext, "UTF-8");



      list.addItem(receivePrint);
    }catch (Exception h){
    }
  }
}


public void actionPerformed(ActionEvent ae)
{
  if(ae.getSource().equals(exitBut))
  System.exit(0);
  else
  {
    try
    {
      String s = text.getText();
      byte[] msg = s.getBytes("UTF-8");
      //encrypt
      //Get public Key
      FileInputStream FISkey = new FileInputStream("publickey.txt");
      ObjectInput oi = new ObjectInputStream(FISkey);  
      Key publicKey = (Key) oi.readObject(); 
      FISkey.close();
      Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
      //encrypt the public key
      cipher.init(Cipher.ENCRYPT_MODE, publicKey);
      byte[] ciphertext = cipher.doFinal(msg);
      String send = new String(ciphertext, "UTF-8");
      bw.write(send);
      bw.newLine();
      bw.flush();
      text.setText("");
    }catch(Exception m){}
  }      
}

}

服务器:

ServerSocket ss;
Socket s;
BufferedReader br;
BufferedWriter bw;
TextField text;
Button sendBut, exitBut;
List list;

public server(String m) // class constructor
{
  super(m);
  setSize(300, 130);
  setLocation(0,0);
  setResizable(true);
  setBackground(new Color(192, 192, 192));
  this.setLayout(new GridLayout(2, 1));

  Panel panels[] = new Panel[2];
  panels[0] = new Panel();
  panels[1] = new Panel();
  panels[0].setLayout(new BorderLayout());
  panels[1].setLayout(new FlowLayout(FlowLayout.LEFT));

  sendBut = new Button("Send");
  exitBut = new Button("Exit");

  sendBut.addActionListener(this);
  exitBut.addActionListener(this);

  list = new List();
  list.addItem("Server up & Listening on port plz wait...");

  text = new TextField(25);

  panels[0].add(list);
  panels[1].add(text);
  panels[1].add(sendBut);
  panels[1].add(exitBut);     

  add(panels[0]);
  add(panels[1]);

  setVisible(true);

  try
  {
    ss = new ServerSocket(1053);//some port number, better be above 1000
    s = ss.accept();
    br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
    bw.write("Hi! Please Enter Your Message Here");
    bw.newLine();
    bw.flush();
    Thread th;
    th = new Thread(this);
    th.start();


  }catch(Exception e){}

}

public void run()
{
  while (true)
  {
    try                       
    {//string toDecrypt = br.readLine();
      //decrypt;
      list.addItem(br.readLine());
    }catch (Exception e){}
  }
}

public static void main(String arg[])
{
  // create an object instance
  // by sending the title as a parameter
  new server("Server Applicaton");
}

public void actionPerformed(ActionEvent ae)
{
  if (ae.getSource().equals(exitBut))
  System.exit(0);
  else
  {
    try
    {       
      String s = text.getText();
      byte[] msg = s.getBytes("UTF-8");
      //encrypt
      //Get public Key
      FileInputStream FISkey = new FileInputStream("publickey.txt");
      ObjectInput oi = new ObjectInputStream(FISkey);  
      Key publicKey = (Key) oi.readObject(); 
      FISkey.close();
      Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
      //encrypt the public key
      cipher.init(Cipher.ENCRYPT_MODE, publicKey);
      byte[] ciphertext = cipher.doFinal(msg);
      String send = new String(ciphertext, "UTF-8");

      bw.write(send);
      bw.newLine();bw.flush();
      text.setText("");
    }catch(Exception x){}
  }

}

请帮帮我!非常感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

您将密文视为字符串。密文的每个字节可以包含任何值。这可能导致数据丢失,因为并非每个字节值都可能具有代表作为字符串中的字符。

答案 1 :(得分:1)

错误填充异常通常表示解密失败。

可能的原因:

  1. 使用了错误的解密密钥
  2. 密文已更改
  3. 使用了错误的填充算法
  4. 在您的情况下,很可能是选项2 - 更改的密文,因为您正在将二进制密码文本转换为字符串。字符串仅适用于可打印字符!

    将密文发送为字节数组并查看它解决了您的问题。

答案 2 :(得分:0)

我将添加一个更多的原因来说明如何获得Bad Padding异常。这是一个愚蠢的愚蠢原因,但我不小心这样做了,您最终会走错路去解决它。

当我解密文本时,我忘记将密码解密并解密。因此,当您调用cipher.doFinal()时,将收到Bad Baddding异常。

相关问题