7

SSLクライアント/サーバーシステム(HTTPなし)をセットアップするためにたくさんのものを読みました。

セキュア チャットの例websocket ssl サーバーの例から着想を得ました。コマンドですでにcert.jksファイルを作成しました

keytool -genkey -alias app-keysize 2048 -validity 36500
-keyalg RSA -dname "CN=app"
-keypass mysecret-storepass mysecret
-keystore cert.jks

セキュア チャットの例では、次のクラスがあります。

public class SecureChatTrustManagerFactory extends TrustManagerFactorySpi {

    private static final TrustManager DUMMY_TRUST_MANAGER = new X509TrustManager() {
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }

        @Override
        public void checkClientTrusted(
                X509Certificate[] chain, String authType) throws CertificateException {
            // Always trust - it is an example.
            // You should do something in the real world.
            // You will reach here only if you enabled client certificate auth,
            // as described in SecureChatSslContextFactory.
            System.err.println(
                    "UNKNOWN CLIENT CERTIFICATE: " + chain[0].getSubjectDN());
        }

        @Override
        public void checkServerTrusted(
                X509Certificate[] chain, String authType) throws CertificateException {
            // Always trust - it is an example.
            // You should do something in the real world.
            System.err.println(
                    "UNKNOWN SERVER CERTIFICATE: " + chain[0].getSubjectDN());
        }
    };

    public static TrustManager[] getTrustManagers() {
        return new TrustManager[] { DUMMY_TRUST_MANAGER };
    }

    @Override
    protected TrustManager[] engineGetTrustManagers() {
        return getTrustManagers();
    }

    @Override
    protected void engineInit(KeyStore keystore) throws KeyStoreException {
        // Unused
    }

    @Override
    protected void engineInit(ManagerFactoryParameters managerFactoryParameters)
            throws InvalidAlgorithmParameterException {
        // Unused
    }
}

このクラスを適切に実装するにはどうすればよいですか?

そして、このコード (SecureChatSslContextFactory クラス) では:

    SSLContext serverContext = null;
    SSLContext clientContext = null;
    try {
        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(SecureChatKeyStore.asInputStream(),
                SecureChatKeyStore.getKeyStorePassword());

        // Set up key manager factory to use our key store
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
        kmf.init(ks, SecureChatKeyStore.getCertificatePassword());

        // Initialize the SSLContext to work with our key managers.
        serverContext = SSLContext.getInstance(PROTOCOL);
        serverContext.init(kmf.getKeyManagers(), null, null);
    } catch (Exception e) {
        throw new Error(
                "Failed to initialize the server-side SSLContext", e);
    }

    try {
        clientContext = SSLContext.getInstance(PROTOCOL);
        clientContext.init(null, SecureChatTrustManagerFactory.getTrustManagers(), null);
    } catch (Exception e) {
        throw new Error(
                "Failed to initialize the client-side SSLContext", e);
    }

なぜ彼らは行のnull代わりに置くのですか?tmf.getTrustManagers()serverContext.init(kmf.getKeyManagers(), null, null);

4

1 に答える 1

9

このクラスを適切に実装するにはどうすればよいですか?

何らかの方法で証明書を信頼していることを確認する方法を定義する必要がありますchain[0]。そうでない場合は、 を投げますCertificateException。(ここでは、SecureChatTrustManagerFactoryは何もスローしないため、検証をバイパスします。これにより、接続が MITM 攻撃に対して開かれる可能性があります。)

この検証を半手動で行う場合は、Java PKI APIを使用できますが、比較的単純なユース ケースであっても、少し面倒な場合があります。

一般的に言えば、正しいことは独自に実装しないことです。それは に任せTrustManagerFactoryます (多かれ少なかれ で行うのと同じ方法KeyManagerFactoryです)。ちなみに、どちらの場合も、正当な理由がない限り、Key/TrustManagerFactory.getDefaultAlgorithm()for の値を使用することをお勧めします。algorithmこれは、少なくとも、SunX509多くの場合にハードコードされている値よりも優れたデフォルト値です (実際には、TMF アルゴリズムのデフォルト値ではありません)。

独自のトラストストアから TMF を初期化できます (たとえば、KeyStoreこの接続専用にロードできる のインスタンス)。

serverContext.init(kmf.getKeyManagers(), null, null); 行に tmf.getTrustManagers() の代わりに null を入れるのはなぜですか? ?

nullトラストマネージャーとデフォルト値へnullSecureRandomフォールバックの場合。これは、デフォルトの TMF アルゴリズム (通常は ) で初期化されたデフォルトのトラスト マネージャでありPKIX、デフォルトのトラスト ストア ( の場所を使用するか、ファイルまたはjavax.net.ssl.trustStoreにフォールバックします) を使用します。詳細については、JSSE リファレンス ガイドを参照してください。jssecacertscacerts

于 2012-07-09T15:03:40.750 に答える