2017-10-05 6 views
0


Nettyを使用して一方向認証ソケットサーバーを構築しようとしています。
私はkeytoolを使ってキーストア、自己署名証明書、トラストストアをサーバーとクライアントの両方に生成し、サーバー/クライアントにいくつかのコードを書きました.SSL認証が機能しています。

ここに私の質問です:
クライアントにトラストストアを追加する必要はありません。私は自分のサーバーにキーストアを追加するだけです。それでもうまくいくでしょうか?私は片方向認証はサーバーだけが証明書を保持していることを意味すると思いましたか?
サーバー:
Nettyを使用する一方向SSL認証

private void addSslHandlerOneWay(SocketChannel ch) throws Exception { 
    SSLContext sslContext = SSLContext.getInstance("TLS"); 

    KeyStore ks = KeyStore.getInstance("JKS"); 
    ks.load(new FileInputStream(new File("svrks.jks")), "kspassword1".toCharArray()); 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
    kmf.init(ks, "kspassword2".toCharArray()); 

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 
    tmf.init(ks); 

    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 
    SSLEngine sslEngine = sslContext.createSSLEngine(); 
    sslEngine.setUseClientMode(false); 
    sslEngine.setNeedClientAuth(false);//one-way 
    sslEngine.setEnabledProtocols(sslEngine.getSupportedProtocols()); 
    sslEngine.setEnabledCipherSuites(sslEngine.getSupportedCipherSuites()); 
    sslEngine.setEnableSessionCreation(true); 

    ch.pipeline().addFirst("SSL", new SslHandler(sslEngine)); 
} 

クライアント:

private void addSslHandlerOneWay(SocketChannel ch) throws Exception { 
    SSLContext sslContext = SSLContext.getInstance("TLS"); 

    KeyStore ts = KeyStore.getInstance("JKS"); 
    ts.load(getInputStream("clits.jks"), "tspassword2".toCharArray()); 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
    kmf.init(ts, "tspassword1".toCharArray()); 

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 
    tmf.init(ts); 

    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 
    SSLEngine sslEngine = sslContext.createSSLEngine(); 
    sslEngine.setUseClientMode(true);//client 

    sslEngine.setEnabledProtocols(sslEngine.getSupportedProtocols()); 
    sslEngine.setEnabledCipherSuites(sslEngine.getSupportedCipherSuites()); 
    sslEngine.setEnableSessionCreation(true); 

    ch.pipeline().addFirst("SSL", new SslHandler(sslEngine)); 
} 

おかげで、みんなを

次は私がこれまでSslHandlerを追加するために自分のサーバー/クライアントで書いたものです。

+0

Steffenの回答に加えて、ほとんどのSSL/TLSクライアント(すべてのWebブラウザを含む)には、Verisign GoDaddyなど、デフォルトで信頼する事前検証済みCAセットがあります。 CAでは、クライアント上でアクションや変更は必要ありません。ほとんどの「本当の」CAはお金を払っていますが、買い物することによって年間数百ドルの基本的な証明書を見つけることができます。 LetsEncryptは何も請求しておらず、広く信頼されていますが、8u101までJavaではデフォルトでは信頼できません。 –

答えて

2

一方向認証は、サーバーだけが証明書を保持していると考えましたか?

サーバーは証明書を使用して自身を認証する必要があります。このためには、証明書と一致する秘密鍵が必要です。
クライアントは認証を検証する必要があります。つまり、サーバーが送信する証明書が実際には期待どおりのものであることが必要です。このためには、証明書自体または証明書を発行したCAのいずれかを知る必要があります。これは自己署名証明書の場合と同じです。

クライアントには、サーバー証明書または発行者CAに関する以前の知識は必要ありません。これが当てはまる場合、クライアントは単に証明書を受け入れ、サーバーからの証明書を訂正し、攻撃者からの証明書も偽装します。以前の知識(すなわち、ローカルトラストアンカー)がなければ、サーバは正しい証明と偽の証明とを区別することができない。

関連する問題