1

我正在尝试在服务器和客户端之间创建一个 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){}
  }

}

请帮我!对你的帮助表示感谢!

4

3 回答 3

2

Bad padding Exception 通常表明解密失败。

可能的原因:

  1. 使用了错误的解密密钥
  2. 密文已更改
  3. 使用了错误的填充算法

在您的情况下,很可能是选项 2 - 更改的密文,因为您正在将二进制密文转换为字符串。字符串仅用于可打印字符!

将密文作为字节数组发送,看看它是否能解决您的问题。

于 2013-01-28T10:40:47.597 回答
1

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

于 2013-01-28T10:33:33.027 回答
0

我将添加另一个原因来说明如何获得 Bad Padding 异常。这是一个愚蠢的愚蠢理由,但我不小心这样做了,你最终会走上错误的道路来试图解决它。

当我解密文本时,我忘记将密码传递给要解密的文本。因此,当您调用 cipher.doFinal() 时,您会得到一个 Bad Padding 异常。

于 2020-12-11T01:33:34.210 回答