2017-02-08 11 views
0

基本的なJavaチャットでSSLを実装するのは非常に困難です。私はサーバーとクライアントを実行することもできましたが、sslの実装に関しては常にクラッシュし、続行できません。JavaチャットでSSLを実装する

私のコードの次の実装はどこから始めるべきですか?私がここに示しているコードは、スイングを使用する非常にシンプルなグラフィカルインターフェイスを持っています。

ClientChat

package clientchat; 

import javax.swing.JOptionPane; 
import static javax.swing.JOptionPane.*; 


public class ClientChat { 

public static void main(String[] args) { 

    String nome = JOptionPane.showInputDialog(null, "Type your name: ", PLAIN_MESSAGE); 

    InterfaceChat chat = new InterfaceChat(name); 
    chat.setVisible(true); 
} 

} 

インターフェイスクライアント

package clientchat; 

import java.awt.event.KeyEvent; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintStream; 
import java.net.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JOptionPane; 
import static javax.swing.JOptionPane.ERROR_MESSAGE; 

public class InterfaceChat extends javax.swing.JFrame { 

private BufferedReader b; 
private InputStreamReader i; 
private String nome; 
private Socket s; 

public InterfaceChat(String nome) { 
    this.nome = nome; 
    try { 
     s = new Socket("127.0.0.1", 5000); 
    } catch (Exception e) { 
     JOptionPane.showMessageDialog(null, "Não se conectou ao servidor", "", ERROR_MESSAGE); 
     System.exit(0); 
    } 
    initComponents(); 

    Thread(); 
} 
private void Thread(){ 
    Thread t = new Thread(new Runnable() { 
    String mensagem;  
     @Override 
     public void run() { 
      try{ 
       i = new InputStreamReader(s.getInputStream()); 
       b = new BufferedReader(i); 

       while((mensagem = b.readLine())!= null){ 
        mensagemRecebida.setText(mensagemRecebida.getText() + mensagem + "\n"); 
       } 

      }catch(IOException e){ 
       JOptionPane.showMessageDialog(null, "Erro na conexão com o servidor","",ERROR_MESSAGE); 
      } 
     } 
    }); 
    t.start(); 
} 

/** 
* This method is called from within the constructor to initialize the form. 
* WARNING: Do NOT modify this code. The content of this method is always 
* regenerated by the Form Editor. 
*/ 
@SuppressWarnings("unchecked") 
// <editor-fold defaultstate="collapsed" desc="Generated Code">       
private void initComponents() { 

    jScrollPane1 = new javax.swing.JScrollPane(); 
    mensagemRecebida = new javax.swing.JTextArea(); 
    jScrollPane2 = new javax.swing.JScrollPane(); 
    enviarMensagem = new javax.swing.JTextArea(); 
    jButton1 = new javax.swing.JButton(); 
    jButton2 = new javax.swing.JButton(); 

    setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); 

    mensagemRecebida.setColumns(20); 
    mensagemRecebida.setRows(5); 
    jScrollPane1.setViewportView(mensagemRecebida); 

    enviarMensagem.setColumns(20); 
    enviarMensagem.setRows(5); 
    enviarMensagem.addKeyListener(new java.awt.event.KeyAdapter() { 
     public void keyPressed(java.awt.event.KeyEvent evt) { 
      enviarMensagemKeyPressed(evt); 
     } 
    }); 
    jScrollPane2.setViewportView(enviarMensagem); 

    jButton1.setText("Enviar"); 
    jButton1.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      jButton1ActionPerformed(evt); 
     } 
    }); 

    jButton2.setText("Sair"); 
    jButton2.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      jButton2ActionPerformed(evt); 
     } 
    }); 

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
    getContentPane().setLayout(layout); 
    layout.setHorizontalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addContainerGap() 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addComponent(jScrollPane1) 
       .addGroup(layout.createSequentialGroup() 
        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 312, javax.swing.GroupLayout.PREFERRED_SIZE) 
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
         .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 99, Short.MAX_VALUE) 
         .addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) 
      .addContainerGap()) 
    ); 
    layout.setVerticalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 
      .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 252, javax.swing.GroupLayout.PREFERRED_SIZE) 
      .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) 
       .addGroup(layout.createSequentialGroup() 
        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) 
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
        .addComponent(jButton2)) 
       .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))) 
    ); 

    pack(); 
}// </editor-fold>       

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           

    String mensagem = nome + ": "; 

    try { 
     PrintStream ps = new PrintStream(s.getOutputStream()); 
     mensagem += enviarMensagem.getText(); 

     ps.println(mensagem); 
     ps.flush(); 
     enviarMensagem.setText(""); 
    } catch (IOException e) { 
     JOptionPane.showMessageDialog(null, "Não conseguiu enviar a mensagem", "", ERROR_MESSAGE); 
    } 
}           

private void enviarMensagemKeyPressed(java.awt.event.KeyEvent evt) {           
    if (evt.getKeyCode() == KeyEvent.VK_ENTER) { 
     String mensagem = nome + ": "; 

     try { 
      PrintStream ps = new PrintStream(s.getOutputStream()); 
      mensagem += enviarMensagem.getText(); 

      ps.println(mensagem); 
      ps.flush(); 
      enviarMensagem.setText(""); 
     } catch (IOException e) { 
      JOptionPane.showMessageDialog(null, "Não conseguiu enviar a mensagem", "", ERROR_MESSAGE); 
     } 
    } 
}           

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {           
    try{ 
     s.close(); 
     System.exit(0); 
    } 
    catch(IOException e){ 
     e.printStackTrace(); 
    } 
}           

// Variables declaration - do not modify      
private javax.swing.JTextArea enviarMensagem; 
private javax.swing.JButton jButton1; 
private javax.swing.JButton jButton2; 
private javax.swing.JScrollPane jScrollPane1; 
private javax.swing.JScrollPane jScrollPane2; 
private javax.swing.JTextArea mensagemRecebida; 
// End of variables declaration     
} 

サーバー

import java.io.IOException; 
import java.io.PrintStream; 
import java.net.*; 
import java.util.ArrayList; 
import javax.net.ssl.SSLServerSocket; 
import javax.net.ssl.SSLServerSocketFactory; 
import javax.net.ssl.SSLSocket; 

public class ServidorChat { 

public static void main(String[] args) { 
    ArrayList<PrintStream> clientes = new ArrayList<>(); 
    try{ 
     SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); 
     SSLServerSocket server = (SSLServerSocket) factory.createServerSocket(5000); 

     while(true){ 
      SSLSocket sslsocket = (SSLSocket) server.accept(); 

      //guarda o endereço dos clientes 
      clientes.add(new PrintStream(sslsocket.getOutputStream())); 
      Mensagem mensagem = new Mensagem(sslsocket, clientes); 
     } 


    } 
    catch(IOException e){ 
     e.printStackTrace(); 
    } 
}} 

メッセージサーバ

public class Mensagem { 

private SSLSocket s; 
private ArrayList<PrintStream> clientes; 

public Mensagem(SSLSocket s, ArrayList<PrintStream> clientes) { 
    this.s = s; 
    this.clientes = clientes; 
    Thread(); 
} 

private void Thread() { 
    Thread t = new Thread(new Runnable() { 

     @Override 
     public void run() { 
      String mensagem = ""; 
      try { 
       InputStreamReader i = new InputStreamReader(s.getInputStream()); 
       BufferedReader b = new BufferedReader(i); 

       while ((mensagem = b.readLine()) != null) { 
        enviarMensagem(mensagem); 
       } 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
    t.start(); 

} 

private void enviarMensagem(String mensagem) { 
    for (int i = 0; i < clientes.size(); i++) { 
     clientes.get(i).println(mensagem); 
     clientes.get(i).flush(); 

サーバーエラー

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection? 
at sun.security.ssl.InputRecord.handleUnknownRecord(InputRecord.java:710) 
at sun.security.ssl.InputRecord.read(InputRecord.java:527) 
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973) 
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) 
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:928) 
at sun.security.ssl.AppInputStream.read(AppInputStream.java:105) 
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) 
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) 
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) 
at java.io.InputStreamReader.read(InputStreamReader.java:184) 
at java.io.BufferedReader.fill(BufferedReader.java:161) 
at java.io.BufferedReader.readLine(BufferedReader.java:324) 
at java.io.BufferedReader.readLine(BufferedReader.java:389) 
at servidorchat.Mensagem$1.run(Mensagem.java:31) 
at java.lang.Thread.run(Thread.java:745) 
+2

「いつもクラッシュする」というのは、役に立つ問題の説明ではありません。詳細を記入してください。 – Berger

+0

あるクライアントから別のクライアントにメッセージを送信する場合、送信されたメッセージは暗号化されただけであり、読み取ることはできません。 –

答えて

-1

あなたは、この目的のためのSSLContextを使用する必要があります。以下のアプリケーションのいずれかで実装したサンプルコードを確認してください。クライアントコンテキストとは、クライアントになってバックエンドを呼び出すことを意味します。サーバーコンテキストとは、クライアント要求を受け入れることを意味します。

public class SSLUtil { 
    private static String KEY_STORE_TYPE = "JKS"; 
    private static String TRUST_STORE_TYPE = "JKS"; 
    private static String KEY_MANAGER_TYPE = "SunX509"; 
    private static String TRUST_MANAGER_TYPE = "SunX509"; 
    private static String PROTOCOL = "TLS"; 

    private static SSLContext serverSSLCtx = null; 
    private static SSLContext clientSSLCtx = null; 

    public static SSLContext createServerSSLContext(final String keyStoreLocation, 
                final String keyStorePwd) 
                      throws KeyStoreException, 
                      NoSuchAlgorithmException, 
                      CertificateException, 
                      FileNotFoundException, 
                      IOException, 
                      UnrecoverableKeyException, 
                      KeyManagementException { 
     if (serverSSLCtx == null) { 
      KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE); 
      keyStore.load(new FileInputStream(keyStoreLocation), keyStorePwd.toCharArray()); 
      KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE); 
      keyManagerFactory.init(keyStore, keyStorePwd.toCharArray()); 
      serverSSLCtx = SSLContext.getInstance(PROTOCOL); 
      serverSSLCtx.init(keyManagerFactory.getKeyManagers(), null, null); 
     } 

     return serverSSLCtx; 
    } 

    public static SSLContext createClientSSLContext(final String trustStoreLocation, 
                final String trustStorePwd) 
                       throws KeyStoreException, 
                       NoSuchAlgorithmException, 
                       CertificateException, 
                       FileNotFoundException, 
                       IOException, 
                       KeyManagementException { 
     if (clientSSLCtx == null) { 
      KeyStore trustStore = KeyStore.getInstance(TRUST_STORE_TYPE); 
      trustStore.load(new FileInputStream(trustStoreLocation), trustStorePwd.toCharArray()); 
      TrustManagerFactory trustManagerFactory = 
                 TrustManagerFactory.getInstance(TRUST_MANAGER_TYPE); 
      trustManagerFactory.init(trustStore); 
      clientSSLCtx = SSLContext.getInstance(PROTOCOL); 
      clientSSLCtx.init(null, trustManagerFactory.getTrustManagers(), null); 
     } 

     return clientSSLCtx; 

    } 

} 

希望します。ハッピーコーディング!

+0

それは完璧に働いた、ありがとう。 –

+0

答えとしてマークしてください。文字通り、これはここでスタックで使用している方法です!とにかく、あなたが作ってくれてうれしいです。 –

+0

あなたはこの目的のために 'SSLContext'を使用する**ではありません。あなたはこれを必要としません。 'javax.net.ssl.keyStore/keyStoreType/keyStorePassword/trustStore/trustStoreType'というシステムプロパティーを使って、まったく同じことを達成することができます。このようなコードを使用する唯一の理由は、異なる 'KeyManagers'または' TrustManagers'をインストールしたい場合です。 – EJP

1
s = new Socket("127.0.0.1", 5000); 

エラーメッセージに記載されているように、プレーンテキスト接続を作成しました。必要があります

s = SSLSocketFactory.getInstance().createSocket("127.0.0.1", 5000); 

その後、サーバー証明書がクライアントによって信頼されている場合は、すべてが動作するはずです。

関連する問題