1

AES 暗号化を使用してデータを送信するチャット プログラム (これに基づく) を作成しようとしていますが、いくつかの問題が発生しまし。私はメッセージをうまく暗号化しました(私は思う... [これは私の2番目のプログラムにすぎないので、私はJavaに本当に慣れていません])が、メッセージを復号化しようとすると、プログラムは以前に作成されたシンボル「暗号」を見つけることができません. エラーの場所は次のとおりです。

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暗号化のコードはこちらから

AES暗号化の部分が関係しているのではないかと疑うのは簡単な解決策だと確信していますが、それを追加することもできます. ご助力いただきありがとうございます!-銀

編集 - エラー:

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)
4

1 に答える 1

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()

于 2013-08-16T22:31:06.900 に答える