【问题标题】:how to solve bad padding如何解决不好的填充
【发布时间】:2013-01-11 11:16:36
【问题描述】:

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

}

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

【问题讨论】:

  • 几个cmets: 1. 你不应该捕捉异常并且什么都不做。至少致电e.printStackTrace()。 2. 如果你能将你的大代码示例压缩成一些小东西来演示问题,你会更快地获得帮助。了解如何创建SSCCE
  • 另请注意,RSA 公钥不能加密大于其模数大小的数据。所以一个 1024 位的 RSA 公钥只能加密 1024 位的数据。 PKCS#1 填充也会占用 11 个字节的数据,因此您最多可以使用 117 个字节。您可能希望对输入进行长度检查或引入会话密钥概念。
  • 一堵巨大的代码墙不如SSCCE

标签: java encryption rsa padding


【解决方案1】:

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

可能的原因:

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

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

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

【讨论】:

  • 当我在为 [maximo] 运行 updatedb 时遇到此错误时,我发现了这个 Q 和 A。问题是属性文件中的 JDBC URL 已更改。该 URL 被 Maximo 的密码加密/解密用作密钥,这意味着我收到错误是因为“使用了错误的解密密钥”。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-10
      • 2012-11-06
      • 2010-11-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多