2013-08-16 2 views
1

Я пытаюсь сделать чат-программу (на основе this), которая использует шифрование AES для отправки данных, но я столкнулся с некоторыми проблемами. Я отлично шифровал сообщения (я думаю ... [Это только моя вторая программа, поэтому я действительно новичок в Java)), но когда я пытаюсь расшифровать сообщение, программа не может найти символ «шифр», который был ранее создан , Heres где ошибка:Не удается найти ошибку Symbol/Variable

public void run() throws IOException { 

// Make connection and initialize streams 
String serverAddress = getServerAddress(); 
Socket socket = new Socket(serverAddress, 9001); 
in = new BufferedReader(new InputStreamReader(
    socket.getInputStream())); 
out = new PrintWriter(socket.getOutputStream(), true); 
// Process all messages from server, according to the protocol. 
while (true) { 
    String line = in.readLine(); 
if (line.startsWith("SUBMITNAME")) { 
     out.println(getName()); 
    } else if (line.startsWith("NAMEACCEPTED")) { 
     textField.setEditable(true); 
    } else if (line.startsWith("MESSAGE")) { 
       //DECRYPTION 
       messageArea.append(line.substring(8) + "\n"); 
       cipher.init(Cipher.DECRYPT_MODE, key); 
       line = new String(cipher.doFinal(line)); 
       System.out.println(line); 
    } 
} 
} 

Хереса, где создается Шифр:

public void actionPerformed(ActionEvent e) { 
    try { 
     String input = (textField.getText()); 
     //ENCRYPTION 
     MessageDigest md5 = MessageDigest.getInstance("MD5"); 
     md5.update("So What's Up Doc?".getBytes()); 

     SecretKeySpec key = new SecretKeySpec(md5.digest(), "AES"); 

     Cipher cipher = Cipher.getInstance("AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, key); 

     byte encryptedMessage[] = cipher.doFinal(input.getBytes()); 
     //Sends the encrypted version of message 
     System.out.println(encryptedMessage); 
     out.println(encryptedMessage); 
     //Clears the input box 
     textField.setText(""); 
    } catch ( NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) { 
     Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    } 

Полный код здесь:

package Chat.Application; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.Socket; 

import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 

import java.security.GeneralSecurityException; 
import java.security.InvalidKeyException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.spec.SecretKeySpec; 
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION; 
/** 
* A simple Swing-based client for the chat server. Graphically 
* it is a frame with a text field for entering messages and a 
* textarea to see the whole dialog. 
* 
* The client follows the Chat Protocol which is as follows. 
* When the server sends "SUBMITNAME" the client replies with the 
* desired screen name. The server will keep sending "SUBMITNAME" 
* requests as long as the client submits screen names that are 
* already in use. When the server sends a line beginning 
* with "NAMEACCEPTED" the client is now allowed to start 
* sending the server arbitrary strings to be broadcast to all 
* chatters connected to the server. When the server sends a 
* line beginning with "MESSAGE " then all characters following 
* this string should be displayed in its message area. 
*/ 
public class ChatClient { 

    BufferedReader in; 
    PrintWriter out; 
    JFrame frame = new JFrame("ELECTRON Chatroom"); 
    JTextField textField = new JTextField(40); 
    JTextArea messageArea = new JTextArea(8, 40); 

    /** 
    * Constructs the client by laying out the GUI and registering a 
    * listener with the textfield so that pressing Return in the 
    * listener sends the textfield contents to the server. Note 
    * however that the textfield is initially NOT editable, and 
    * only becomes editable AFTER the client receives the NAMEACCEPTED 
    * message from the server. 
    */ 
    public ChatClient() { 

     // Layout GUI 
     textField.setEditable(false); 
     messageArea.setEditable(false); 
     messageArea.setWrapStyleWord(true); 
     messageArea.setLineWrap(true); 
     frame.getContentPane().add(textField, "North"); 
     frame.getContentPane().add(new JScrollPane(messageArea), "Center"); 
     frame.pack(); 
     // Add Listeners 
     textField.addActionListener(new ActionListener() { 
      /** 
      * Responds to pressing the enter key in the textfield by sending 
      * the contents of the text field to the server. Then clear 
      * the text area in preparation for the next message. 
      */ 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      try { 
       String input = (textField.getText()); 
       //ENCRYPTION 
       MessageDigest md5 = MessageDigest.getInstance("MD5"); 
       md5.update("So What's Up Doc?".getBytes()); 

       SecretKeySpec key = new SecretKeySpec(md5.digest(), "AES"); 

       Cipher cipher = Cipher.getInstance("AES"); 
       cipher.init(Cipher.ENCRYPT_MODE, key); 

       byte encryptedMessage[] = cipher.doFinal(input.getBytes()); 
       //Sends the encrypted version of message 
       System.out.println(encryptedMessage); 
       out.println(encryptedMessage); 
       //Clears the input box 
       textField.setText(""); 
      } catch ( NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) { 
       Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex); 
      } 
      } 
     }); 
    } 

    /** 
    * Prompt for and return the address of the server. 
    */ 
    private String getServerAddress() { 
     return JOptionPane.showInputDialog(
      frame, 
      "Enter IP Address of the Server:", 
      "ELECTRON Chatroom", 
      JOptionPane.QUESTION_MESSAGE); 
    } 

    /** 
    * Prompt for and return the desired screen name. 
    */ 
    private String getName() { 
     return JOptionPane.showInputDialog(
      frame, 
      "Choose a screen name:", 
      "Screen name selection", 
      JOptionPane.PLAIN_MESSAGE); 
    } 

    /** 
    * Connects to the server then enters the processing loop. 
    */ 
    public void run() throws IOException { 

     // Make connection and initialize streams 
     String serverAddress = getServerAddress(); 
     Socket socket = new Socket(serverAddress, 9001); 
     in = new BufferedReader(new InputStreamReader(
      socket.getInputStream())); 
     out = new PrintWriter(socket.getOutputStream(), true); 
     // Process all messages from server, according to the protocol. 
     while (true) { 
      String line = in.readLine(); 
     if (line.startsWith("SUBMITNAME")) { 
       out.println(getName()); 
      } else if (line.startsWith("NAMEACCEPTED")) { 
       textField.setEditable(true); 
      } else if (line.startsWith("MESSAGE")) { 
         //DECRYPTION 
         messageArea.append(line.substring(8) + "\n"); 
         cipher.init(Cipher.DECRYPT_MODE, key); 
         line = new String(cipher.doFinal(line)); 
         System.out.println(line); 
      } 
     } 
    } 

    /** 
    * Runs the client as an application with a closeable frame. 
    */ 
    public static void main(String[] args) throws Exception { 
     ChatClient client = new ChatClient(); 
     client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     client.frame.setVisible(true); 
     client.run(); 
    } 
} 

код шифрование AES составляет от here

Я уверен, что это простое решение, сомнение в том, что часть шифрования AES имеет какое-либо отношение к i t, но может также добавить его. Спасибо за вашу помощь! -серебро

EDIT - ОШИБКА:

no suitable method found for doFinal(String) 
    method Cipher.doFinal(ByteBuffer,ByteBuffer) is not applicable 
     (actual and formal argument lists differ in length) 
    method Cipher.doFinal(byte[],int,int,byte[],int) is not applicable 
     (actual and formal argument lists differ in length) 
    method Cipher.doFinal(byte[],int,int,byte[]) is not applicable 
     (actual and formal argument lists differ in length) 
    method Cipher.doFinal(byte[],int,int) is not applicable 
     (actual and formal argument lists differ in length) 
    method Cipher.doFinal(byte[]) is not applicable 
     (actual argument String cannot be converted to byte[] by method invocation conversion) 
    method Cipher.doFinal(byte[],int) is not applicable 
     (actual and formal argument lists differ in length) 
    method Cipher.doFinal() is not applicable 
     (actual and formal argument lists differ in length) 

ответ

1

Сделать cicher глобальной переменной. Объявить его на верхнем уровне вашего класса:

Cipher cipher; 

Изменение:

Cipher cipher = Cipher.getInstance("AES"); 

к:

cipher = Cipher.getInstance("AES"); 

Добавить чек на null здесь:

if (cipher != null) { 
    cipher.init(Cipher.DECRYPT_MODE, key); 
    line = new String(cipher.doFinal(line)); 
    System.out.println(line); 
} 

В основном , переменная cipher не известно, где вы пытаетесь его использовать. Объявление его на верхнем уровне сделает его видимым во всем классе. Проверка null не требуется, если в этом actionPerformed(ActionEvent) и run() вызывается номер <.

+0

Все стало лучше, за исключением строки, которая включает в себя «line = new String (cipher.doFinal (строка)); где есть довольно большая ошибка. Я перечислил ошибку в моем вопросе – Silver

+0

Любая идея о том, как ее исправить? Также спасибо за помощь! – Silver

+0

@Silver Вы видите, что ошибка beacuse: 'Cipher.doFinal()' является перегруженным методом, и ни одна из сигнатур метода не соответствует - 'Cipher.doFinal (String)', которую вы пытаетесь сделать. Взгляните на API Cipher и убедитесь, что 'Cipher.doFinal (String)' не существует. Я бы предложил вам оставить 'AES' сейчас. – Vikram

Смежные вопросы