2017-01-30 2 views
3

org.restlet.engine.ssl.DefaultSslContextFactoryを使用する既存のアプリケーションと、サーバーの起動時にロードされるキーストアファイルがあります。 サーバーが稼動している間に、キーストアファイルに を動的に追加する必要がある証明書を作成する別のアプリケーションがあります。これを実行するには、 コードに証明書と秘密鍵を作成し、 をディレクトリに書き込みます。このディレクトリは、新しいファイルをチェックするbashスクリプトによって監視され、存在する場合は、既存のキーストアファイルにインポートされます。Java DefaultSslContextFactoryキーストアの動的更新

しかし、新しくインポートされた証明書でサーバーにアクセスしようとすると、ハンドシェイクは失敗します。サーバーを再起動するときだけ、アクセスは正常に完了することができます。これは、追加された証明書がサーバーによって再ロードされないことを意味します。

実行中のアプリケーションをキーストアファイルの新しいエントリで更新する方法はありますか?

+0

この回答をお探しですか? http://stackoverflow.com/questions/859111/how-can-i-use-different-certificates-on-specific-connections – Tom

答えて

0

新しい証明書をキーストアにインポートしても、キーストアが変更されたことをJVMに知らせるものがないため、現在のSSLConextは更新されません。

これを行うには、新しい証明書がキ​​ーストアに追加されたことをアプリケーションに伝える必要がありますが、鍵ストアを再ロードするのではなく、可能ではないとわかっています現在のSSLContext See hereに新しい証明書を追加できることです。

これを達成するには、SSLContextインスタンスを注入した新しい証明書(あなたのbashスクリプトを呼び出すコンポーネントかもしれません)を認識したBeanを提供する必要があります。

マイクロサービスアーキテクチャを使用してアプリケーションを分割し、証明書を扱うファクトを1つのモジュールに委任し、キーストアが更新されるときに適切な構成LBを使用して再ロードすることも面白いです。

+0

最後の段落の意味を理解できません。 bashスクリプトは単独で実行されているため、インスタンスを挿入する場所はどこですか? – wasp256

+0

あなたのJavaコードには、メモリ証明書チェーンでリフレッシュするコードがあります。 –

+0

それは非常に汚れたハックのように聞こえる... – wasp256

0

これは非常に不可能な作業であると思われるので、私は回避策を講じることにしました。私はアプリケーションの前でプロキシとしてnginxを使用しました。 Nginxは、私が必要とするものである複数のCAルート証明書を使ってクライアント認証を実行することができます。アプリケーションとnginxとの接続は、同じホスト(異なるポート)に存在するため、HTTP経由で簡単に行うことができます。

0

醜いハックアラート

私のために次のような作品。私はDefaultSSLContextFactoryを上書きし、作成された各SSLContextを保存し、initメソッドを再度呼び出します。

私は単にUglyHackSSLContextFactory.reloadKeyStoreを(呼び出しリロードを呼び出すために)

package test; 

import java.io.FileInputStream; 
import java.io.IOException; 
import java.security.KeyManagementException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.NoSuchProviderException; 
import java.security.SecureRandom; 
import java.security.UnrecoverableKeyException; 
import java.security.cert.CertificateException; 
import java.util.ArrayList; 

import javax.net.ssl.SSLContext; 

import org.restlet.engine.ssl.DefaultSslContextFactory; 

public class UglyHackSSLContextFactory extends DefaultSslContextFactory { 

    private SSLContext _context = null; 
    public static ArrayList<UglyHackSSLContextFactory> instances = new ArrayList<UglyHackSSLContextFactory>(); 

    // we need all used SSLContextFactories later, so store them 
    public UglyHackSSLContextFactory() { 
     instances.add(this); 
    } 

    // create a new context once and store it. 
    @Override 
    public SSLContext createSslContext() throws Exception { 
     if (this._context == null) { 
      this._context = super.createSslContext(); 
     } 
     return this._context; 
    } 

    // re-init all _context instances 
    public static void reload() throws KeyManagementException, UnrecoverableKeyException, 
      KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, 
      CertificateException, IOException { 
     for (final UglyHackSSLContextFactory f : instances) { 
      f.reinit(); 
     } 
    } 

    // this is mostly copied from 
    // org.restlet.engine.ssl.DefaultSslContextFactory 
    private void reinit() throws KeyManagementException, KeyStoreException, 
      NoSuchProviderException, NoSuchAlgorithmException, CertificateException, IOException, 
      UnrecoverableKeyException { 

     javax.net.ssl.KeyManagerFactory kmf = null; 

     if ((getKeyStorePath() != null) || (getKeyStoreProvider() != null) 
       || (getKeyStoreType() != null)) { 
      // Loads the key store. 
      final KeyStore keyStore = (getKeyStoreProvider() != null) ? KeyStore.getInstance(
        (getKeyStoreType() != null) ? getKeyStoreType() : KeyStore.getDefaultType(), 
        getKeyStoreProvider()) : KeyStore 
        .getInstance((getKeyStoreType() != null) ? getKeyStoreType() : KeyStore 
          .getDefaultType()); 
      FileInputStream keyStoreInputStream = null; 

      try { 
       keyStoreInputStream = ((getKeyStorePath() != null) && (!"NONE" 
         .equals(getKeyStorePath()))) ? new FileInputStream(getKeyStorePath()) 
         : null; 
       keyStore.load(keyStoreInputStream, getKeyStorePassword()); 
      } finally { 
       if (keyStoreInputStream != null) { 
        keyStoreInputStream.close(); 
       } 
      } 

      // Creates the key-manager factory. 
      kmf = javax.net.ssl.KeyManagerFactory.getInstance(getKeyManagerAlgorithm()); 
      kmf.init(keyStore, getKeyStoreKeyPassword()); 
     } 

     javax.net.ssl.TrustManagerFactory tmf = null; 

     if ((getTrustStorePath() != null) || (getTrustStoreProvider() != null) 
       || (getTrustStoreType() != null)) { 
      // Loads the trust store. 
      final KeyStore trustStore = (getTrustStoreProvider() != null) ? KeyStore 
        .getInstance(
          (getTrustStoreType() != null) ? getTrustStoreType() : KeyStore 
            .getDefaultType(), getTrustStoreProvider()) : KeyStore 
        .getInstance((getTrustStoreType() != null) ? getTrustStoreType() : KeyStore 
          .getDefaultType()); 
      FileInputStream trustStoreInputStream = null; 

      try { 
       trustStoreInputStream = ((getTrustStorePath() != null) && (!"NONE" 
         .equals(getTrustStorePath()))) ? new FileInputStream(getTrustStorePath()) 
         : null; 
       trustStore.load(trustStoreInputStream, getTrustStorePassword()); 
      } finally { 
       if (trustStoreInputStream != null) { 
        trustStoreInputStream.close(); 
       } 
      } 

      // Creates the trust-manager factory. 
      tmf = javax.net.ssl.TrustManagerFactory.getInstance(getTrustManagerAlgorithm()); 
      tmf.init(trustStore); 
     } 

     SecureRandom sr = null; 

     if (getSecureRandomAlgorithm() != null) { 
      sr = SecureRandom.getInstance(getSecureRandomAlgorithm()); 
     } 

     this._context.init(kmf != null ? kmf.getKeyManagers() : null, 
       tmf != null ? tmf.getTrustManagers() : null, sr); 

    } 

} 

・ホープ、このことができます!