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 に答える