2013-08-16 6 views
1

AES 암호화를 사용하여 데이터를 보내는 채팅 프로그램 (기반은 this)을 만들려고 시도했지만 몇 가지 문제가 있습니다. 나는 메시지를 잘 암호화했다. (이것은 제 두 번째 프로그램이므로 자바에 처음으로 익숙하다.) 그러나 메시지를 해독하려고하면 프로그램은 이전에 생성 된 "암호"라는 기호를 찾을 수 없다. . Heres는 오류가이다 :기호/변수 오류를 찾을 수 없습니다.

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); 
    } 
} 
} 

암호가 생성됩니다 Heres는 :

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와 아무런 상관이없는 쉬운 해결책이라고 확신한다. 그러나 그것을 추가 할 수도 있습니다. 모든 도움을 주셔서 감사합니다! 편집

- 실버 - ERROR :

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"); 

에 : 기본적으로

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

:

cipher = Cipher.getInstance("AES"); 

여기 null에 대한 검사를 추가하여 클래스의 최상위 수준에 선언 , 변수 cipher은 어디에서 사용하려고하는지 알 수 없습니다. 최상위 수준에서 선언하면 클래스 전체에 표시됩니다. 이 < 주문에서 actionPerformed(ActionEvent)run()을 호출하면 null 수표가 필요하지 않습니다.

+0

"line = new String (cipher.doFinal (line));"을 포함하는 행을 제외한 모든 것이 더 좋아졌습니다. 꽤 큰 오류가있는 곳. 내 질문에 오류가 나열된 – Silver

+0

그것을 고칠 수있는 방법에 대한 아이디어? 또한 모든 도움에 감사드립니다! – Silver

+0

@Silver 오류가 발생하는 것을 볼 수 있습니다 :'Cipher.doFinal()'은 오버로드 된 메서드이고 메소드 시그니처 중 어떤 것도 시도하지 않습니다 - 당신이하려고하는'Cipher.doFinal (String)'. Cipher API를보고 'Cipher.doFinal (String)'이 존재하지 않는지 확인하십시오. 나는 지금 당신이'AES'를 떠날 것을 제안 할 것입니다. 어쨌든 고마워 고마워, – Vikram

관련 문제