Javaメモ - SSL Socketを使った通信
in

JavaでSSLを使ってソケット通信するサンプル。元ネタはこの辺り。

http://codezine.jp/article/detail/105?p=1
http://mikilab.doshisha.ac.jp/dia/research/report/2005/0918/004/report20050918004.html

僕のサンプルではクライアントの証明書の認証は行わない。単にサーバーが送ってきた証明書をクライアントで認証するだけである。つまりサーバーはクライアントがどんなものであっても受け入れる。ウェブサーバーとかは普通こうなっているから。

クライアント側コード SSLClient.java

import java.io.*;
import java.security.KeyStore;

import javax.net.ssl.*;

public class
SSLClient {

public static
void main(String[] args) {
  try {
  
  
// TrustStoreを読み込む
  
KeyStore trust_store = KeyStore.getInstance("JKS");

  
// changit はclientTrustを作ったときのパスワード
  
char[] trust_pass = "changeit".toCharArray();
  
trust_store.load(new FileInputStream("C:\\Temp\\clientTrust"),
   
trust_pass);
  
  
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
   
"SunX509");
  
tmf.init(trust_store);
  
  
// ソケットを生成する
  
SSLContext context = SSLContext.getInstance("TLS");
  
context.init(null, tmf.getTrustManagers(), null);
  
SSLSocketFactory sf = context.getSocketFactory();
  
SSLSocket soc = (SSLSocket)sf.createSocket("192.168.1.100", 51004);
  
soc.startHandshake();
  
  
// 入出力ストリームを取得する
  
ObjectOutputStream oos = new ObjectOutputStream(
   
soc.getOutputStream());
  
ObjectInputStream ois = new ObjectInputStream(
   
soc.getInputStream());
  
  
// 出力ストリームにオブジェクトを書き出す
  
oos.writeObject(args[0]);
  
  
// 入力ストリームからオブジェクトを取得する
  
String str = (String)ois.readObject();
  
  
// サーバの処理結果を表示する
  
System.out.println("string to uppercase : " + str);
  
  
// ストリーム・ソケットを閉じる
  
oos.close();
  
ois.close();
  
soc.close();
  } catch(
Exception e) {
  
e.printStackTrace();
  }
}
}

サーバー側コード 

Server.java

import java.io.FileInputStream;
import java.net.*;
import java.security.KeyStore;

import javax.net.ssl.*;

public class
Server {

public static
void main(String[] args) {
  try {
  
      
// KeyStoreを読み込む
      
KeyStore key_store = KeyStore.getInstance("JKS");
      
char[] key_pass = "changeit".toCharArray();
      
key_store.load(new FileInputStream("C:\\Temp\\keystore"),
       
key_pass);
      
      
KeyManagerFactory kmf = KeyManagerFactory.getInstance(
       
"SunX509");
      
kmf.init(key_store, key_pass);
      
      
// サーバソケットを生成する
      
SSLContext context = SSLContext.getInstance("TLS");
      
context.init(kmf.getKeyManagers(), null, null);
      
SSLServerSocketFactory ssf =
       
context.getServerSocketFactory();
      
SSLServerSocket ssoc = (SSLServerSocket)
       
ssf.createServerSocket(51004);
      

  
   while(
true) {
    try {
    
System.out.println("waiting for connection from client");
    
// クライアントからの接続を待つ
    
Socket soc = ssoc.accept();
    
System.out.println("receive client!");
    
    
// 処理をConnectに任せる
    
new Connect(soc);
    } catch(
Exception e) {
    
e.printStackTrace();
    }
   }
  } catch(
Exception e) {
  
e.printStackTrace();
  }
}
}

Connect.java

import java.io.*;
import java.net.*;

public class
Connect extends Thread {

private
Socket soc = null;

public
Connect(Socket soc) {
 
this.soc = soc;
 
 
// スレッドを開始する
 
this.start();
}

public
void run() {
  try {
  
// 入出力ストリームを取得する
  
ObjectInputStream ois = new ObjectInputStream(
       
soc.getInputStream());
  
ObjectOutputStream oos = new ObjectOutputStream(
       
soc.getOutputStream());
  
  
// 入力ストリームからオブジェクトを取得する
  
String str = (String)ois.readObject();
  
  
// 文字列を大文字に変換する
  
str = str.toUpperCase();
  
  
// 出力ストリームにオブジェクトを書き出す
  
oos.writeObject(str);
  
  
// ストリーム・ソケットを閉じる
  
ois.close();
  
oos.close();
  
soc.close();
  } catch(
Exception e) {
  
e.printStackTrace();
  }
}
}

証明書とかキーストアの作り方は上の元ネタで確認してください。

新しいコメントの投稿

このフィールドの内容は非公開にされ、公表されることはありません。
  • ウェブページアドレスとメールアドレスは、自動的にハイパーリンクに変換されます。
  • 使用できるHTMLタグ: <a> <em> <strong> <code> <cite> <ul> <ol> <li> <dl> <dt> <dd> <p>
  • 行と段落は自動的に折り返されます。
  • Amazon製品へのリンクを次の形式で作成することが出来ます。[amazon product_id inline|full|thumbnail]. 例: [amazon 1590597559 thumbnail]
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • 画像を追加することが出来ます。

書式オプションに関するより詳しい情報...

認証コード
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
画像で表示されている数字および記号を入力してください。