0

Androidとサーバー側でNettyを使用して、クライアント認証でSSLで保護された接続を確立しています。SSLEngine が「null cert chain」のために証明書を拒否するため、これらの証明書に接続するのに問題があります。

これは、サーバー側で行ったことです。署名済みのサーバー証明書を使用して SSLContext をセットアップしました (クライアントは CA を認識しているため、これを検証できます)。

サーバーがクライアントからの証明書を受け入れるようにするために (証明書はすべて自己署名であるため)、すべてを受け入れる DummyTrustManager を実装しました。

private static class DummyTrustManager implements X509TrustManager
    {
        private X509Certificate[] mCerts;

        public DummyTrustManager(Certificate[] pCerts)
        {
            // convert into x509 array
            mCerts = new X509Certificate[pCerts.length];
            for(int i = 0; i < pCerts.length; i++)
            {
                mCerts[i] = (X509Certificate)pCerts[i];
            }
        }

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{}

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{}

        @Override
        public X509Certificate[] getAcceptedIssuers()
        {
            return mCerts;
            //return new X509Certificate[0];
        }
    }

ポイントは、getAcceptedIssuers() メソッドについてよくわからないということです。

  • 空の配列を返すと、空の AcceptedIssuers リストが原因で、openssl-binary (正しいセットアップを検証するために使用します) が失敗します。

  • 現在のサーバー証明書チェーンを追加すると、少なくとも同じ CA によって署名されたクライアント証明書では機能しますが、自己署名されたものでは機能しません (これが必要です)。

しかし、クライアント側で何か間違ったことをしているのかもしれません:

        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null);

        keyStore.setEntry("user_certificate", new KeyStore.PrivateKeyEntry(mPrivate, new Certificate[]{mClientCert}), this);
        keyStore.setCertificateEntry("server_certificate", mServerCert);

また、いくつかの調査を行い、これまでに理解したことから、クライアントには有効な証明書チェーンがありますが、サーバーによってリストされた発行者のみを受け入れるとサーバーが通知するため、送信しません。

これが正しい場合、どうすればこの問題を克服できますか?

私は、すべてのクライアントに配信され、サーバーの承認済み発行者リストにも記載されている個別の自己署名 CA を考えていました。どのクライアントも、この CA を使用して独自の証明書に署名します。これにはセキュリティ上の問題はないと思います。または、より良い解決策はありますか?

4

1 に答える 1