2017-04-11 5 views
0

こんにちは私は、クライアントとクライアント認証をtrueに設定してSSLソケットを使用するサーバーとのJavaプロジェクトに取り組んでいます。私はすべてが機能していますが、私は自分たちの両側に何を入れるべきかを確かめたいと思います。クライアントとjava socketSSLとの通信。本当に必要な証明書

クライアント
1.クライアントの秘密鍵(key.pem)&公開鍵(cert.pemに)。
2.中間CA公開鍵(cert.pem)。

サーバー
1.サーバーの秘密鍵(key.pem)&公開鍵(cert.pemに)。
2.中間CA公開鍵(cert.pem)。

私は証明書について多くのことを読んできましたが、本当に必要な証明書は本当に理解できません。

質問

1.私はクライアントだけROOTCAのCAと彼の証明書、およびサーバーのすべてのチェーンと彼の証明書が含まれている必要があります読んで。これはこれを正しく処理する方法ですか?

2.私は、サーバーには証明書を持つものとトラステッドチェーンを持つものの2つのjkが必要であることも読んでいます。私はそれぞれが何を含んでいるのか本当に分かりません。

3.コードは、サーバーとクライアントがjavax.net.ssl.keyStoreとjavax.net.ssl.trustStoreを持つ場合にのみ機能します。私がそれらの1つを取り除くと、彼らは仕事をやめ、なぜですか?私が読んだことから、クライアントはtrustStoreだけで作業できるはずです。

私はインターネットに多くの情報があることを知っています。私はそれについて1週間読んで過ごしましたが、私はまだこの点を解決できません。コードが機能しているにもかかわらず、なぜそれが動作するのか、それを行う正しい方法は何かを知りたいのです。

私は、以下のウェブサイトのtutorilaからバッチを作成しました:https://jamielinux.com/docs/openssl-certificate-authority/

私はセカンダリプロジェクトを使用して、sslソケット接続をテストしています。

クライアント(MWE)

package com.test.ssl; 

import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

import javax.net.ssl.SSLSocket; 
import javax.net.ssl.SSLSocketFactory; 


public class Client { 

    private static final String IP = "127.0.0.1"; 
    private static final int PORT = 15000; 
    private static DataOutputStream os; 
    private static DataInputStream is; 
    private static final byte messageEnd = 0; 

    public static void main(String[] args) { 
     System.setProperty("javax.net.ssl.keyStore", "D:\\workspace\\Client_Server_SSL\\clientKeyStore.jks"); 
     System.setProperty("javax.net.ssl.keyStorePassword", "CertPass"); 
     System.setProperty("javax.net.ssl.trustStore", "D:\\workspace\\Client_Server_SSL\\clientKeyStore.jks"); 
     System.setProperty("javax.net.ssl.trustStorePassword", "CertPass"); 

     SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); 

     try { 
      SSLSocket sslsocket = (SSLSocket) factory.createSocket(IP, PORT); 
      sslsocket.setNeedClientAuth(true); 
      is = new DataInputStream(sslsocket.getInputStream()); 
      System.out.println("Loading output streams"); 
      os = new DataOutputStream(sslsocket.getOutputStream()); 
      System.out.println("Streams loaded"); 
      os.write("Hi\0".getBytes()); 

      byte character; 
      List<Byte> message = new ArrayList<>(); 
      while ((character = is.readByte()) != messageEnd) { 
       message.add(character); 
      } 

      byte[] messageBytes = byteListToByteArray(message); 
      String response = new String(messageBytes); 
      System.out.println("Server response: " + response); 

     } catch (IOException e) { 

      e.printStackTrace(); 
     } 

    } 

    public static byte[] byteListToByteArray(List<Byte> bytes) { 
     byte[] result = new byte[bytes.size()]; 
     for (int i = 0; i < bytes.size(); i++) { 
      result[i] = bytes.get(i).byteValue(); 
     } 

     return result; 
    } 

} 

サーバー(MWE)

package com.test.ssl; 

import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

import javax.net.ssl.SSLServerSocket; 
import javax.net.ssl.SSLServerSocketFactory; 
import javax.net.ssl.SSLSocket; 

public class Server { 

    private static boolean serverListening = true; 
    private static SSLServerSocket sslserversocket; 
    private static final int PORT = 15000; 
    private static DataInputStream is; 
    private static DataOutputStream os; 

    public static void main(String[] args) { 
     System.setProperty("javax.net.ssl.keyStore", "D:\\workspace\\Client_Server_SSL\\serverKeyStore.jks"); 
     System.setProperty("javax.net.ssl.keyStorePassword", "CertPass"); 
     System.setProperty("javax.net.ssl.trustStore", "D:\\workspace\\Client_Server_SSL\\serverKeyStore.jks"); 
     System.setProperty("javax.net.ssl.trustStorePassword", "CertPass"); 

     SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); 

     try { 
      sslserversocket = (SSLServerSocket) factory.createServerSocket(PORT); 
      sslserversocket.setNeedClientAuth(true); 
      while (serverListening) { 
       System.out.println("Waiting for client"); 
       // Accept return a new socket to handle the client. 
       SSLSocket sslsocket = (SSLSocket) sslserversocket.accept(); 

       is = new DataInputStream(sslsocket.getInputStream()); 
       os = new DataOutputStream(sslsocket.getOutputStream()); 
       System.out.println("Client connected"); 

       List<Byte> message = new ArrayList<>(); 
       byte character; 

       while ((character = is.readByte()) != 0) { 
        message.add(character); 
       } 

       byte[] messageBytes = byteListToByteArray(message); 
       String response = new String(messageBytes); 
       System.out.println("Client sad: " + response); 

       os.write("Welcome\0".getBytes()); 
      } 
     } catch (IOException e) { 
      System.err.println("Exception: " + e); 
     } 

    } 

    public static byte[] byteListToByteArray(List<Byte> bytes) { 
     byte[] result = new byte[bytes.size()]; 
     for (int i = 0; i < bytes.size(); i++) { 
      result[i] = bytes.get(i).byteValue(); 
     } 

     return result; 
    } 

} 

バッチスクリプト:

はダウンロードをこれは私が使用しているものですopenSSL from:https://slproweb.com/products/Win32OpenSSL.html
binフォルダを別のフォルダにコピーし、バッチファイルをそこに追加しました。 openssl.cnfは、最初のリンクからのガイドのコピーです。

@echo on 

cd /D %~dp0 

REM could not create all subfolder at onces, I got a syntax error when trying root\ca\{certs,crl,newcerts,private} 
mkdir root\ca\certs 
mkdir root\ca\crl 
mkdir root\ca\newcerts 
mkdir root\ca\private 
type NUL > root\ca\index.txt 
echo 1000 > root\ca\serial 
REM tried to use type but it was not working. 
copy "%~dp0ConfigurationFiles\openssl_ca_test.cnf" root\ca\openssl.cnf 

@echo ______________Creating CA 

openssl genrsa -aes256 -out root/ca/private/ca.key.pem -passout pass:CAPassword 4096 

openssl req -config root/ca/openssl.cnf -key root/ca/private/ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out root/ca/certs/ca.cert.pem -passin pass:CAPassword 

openssl x509 -noout -text -in root/ca/certs/ca.cert.pem 

@echo ______________INTERMEDIATE CERTIFICATES 

mkdir root\ca\intermediate\certs 
mkdir root\ca\intermediate\crl 
mkdir root\ca\intermediate\newcerts 
mkdir root\ca\intermediate\private 
mkdir root\ca\intermediate\csr 
type NUL > root\ca\intermediate\index.txt 
echo 1000 > root\ca\intermediate\serial 
echo 1000 > root\ca\intermediate\crlnumber 
copy "%~dp0ConfigurationFiles\openss_intermediate_test.cnf" root\ca\intermediate\openssl.cnf 

openssl genrsa -aes256 -out root/ca/intermediate/private/intermediate.key.pem -passout pass:InterMPassword 4096 

openssl req -config root/ca/intermediate/openssl.cnf -new -sha256 -key root/ca/intermediate/private/intermediate.key.pem -out root/ca/intermediate/csr/intermediate.csr.pem -passin pass:InterMPassword 

openssl ca -config root/ca/openssl.cnf -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in root/ca/intermediate/csr/intermediate.csr.pem -out root/ca/intermediate/certs/intermediate.cert.pem -passin pass:CAPassword 

type root\ca\intermediate\certs\intermediate.cert.pem root\ca\certs\ca.cert.pem > root\ca\intermediate\certs\ca-chain.cert.pem 


@echo ______________GENERATING CERTIFICATES 

openssl genrsa -aes256 -out root/ca/intermediate/private/www.client.com.key.pem -passout pass:CertPass 2048 

openssl genrsa -aes256 -out root/ca/intermediate/private/www.server.com.key.pem -passout pass:CertPass 2048 

openssl req -config root/ca/intermediate/openssl.cnf -key root/ca/intermediate/private/www.client.com.key.pem -new -sha256 -out root/ca/intermediate/csr/www.client.com.csr.pem -passin pass:CertPass 

openssl req -config root/ca/intermediate/openssl.cnf -key root/ca/intermediate/private/www.server.com.key.pem -new -sha256 -out root/ca/intermediate/csr/www.server.com.csr.pem -passin pass:CertPass 

@echo ______________SIGNING CERTIFICATES 

openssl ca -config root/ca/intermediate/openssl.cnf -extensions usr_cert -days 7000 -notext -md sha256 -in root/ca/intermediate/csr/www.client.com.csr.pem -out root/ca/intermediate/certs/www.client.com.cert.pem -passin pass:InterMPassword 

openssl ca -config root/ca/intermediate/openssl.cnf -extensions server_cert -days 7000 -notext -md sha256 -in root/ca/intermediate/csr/www.server.com.csr.pem -out root/ca/intermediate/certs/www.server.com.cert.pem -passin pass:InterMPassword 

@echo ______________DONE 

PAUSE 

答えて

1

私はそれぞれの側が自分のJKSに含めるべきかを確認してくださいしたいと思います。キーストアおよびトラストストア:

まず、相互認証SSLのために、それぞれの側は JKSファイルを必要とします。これらのファイルを混乱させたり、目的を融合させたり、両方のファイルを1つずつ使用したりしないでください。

鍵ストアには、それぞれその側の秘密鍵と証明書と、ピアによって信頼されているルートCAまでの署名付き証明書チェーンが含まれています。

それぞれの場合のトラストストアには、この側が信頼するルートCAが含まれています。ピアが自己署名証明書を使用して不幸な理由がある場合、これは、この側のトラストストアでその証明書のエクスポートされたコピーを要求することになります。

+0

私は理解していますが、まだいくつか質問があります。正確に証明書チェーンとは何ですか(それは独自の証明書には含まれていません)。 Oと、中間CAのみで作業するのはなぜですか(ルートなし)。 – MissingSemiColon

+1

はい、それぞれの側で異なるCAを持つことができます。通常、両側のトラストストアはJREに付属しているトラストストアになります。ルート証明機関には* lots *のルートCA証明書が含まれています。トラストストアには、受信した証明書チェーン内に* a *の証明書が含まれていなければなりません。通常これはルートになりますが、場合によっては中間のルートになる場合もあります。証明連鎖は、CAが署名した証明書から始まり、すべての内部証明書を経由して自分のルートCA証明書に転送します。 – EJP

+0

ありがとう、ルート証明書と中間コードを追加することをお勧めしますか?私は中間体を共有するだけで安全だと読んだ。もう一度、すばやく明確な答えを感謝します。 – MissingSemiColon

関連する問題