接受SSL握手中的任何客户端证书

时间:2013-05-14 15:15:28

标签: java android ssl ssl-certificate sslengine

我在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()方法不太确定。

  • 如果我重新开始一个空数组而不是openssl-binary(我用它来设置正确的设置)由于一个空的AcceptedIssuers列表而失败。

  • 如果我添加当前服务器证书链,它至少可以用于由同一个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签署自己的证书。我发现没有安全问题。或者有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

由于长期没有答案,我现在简要概述一下如何解决这个问题。

我创建了另一个未经任何可信CA签名的CA.实际上它是自签名的。该CA将授予所有客户签署自己的证书。为什么?因为这样我可以告诉服务器将此CA作为唯一接受的getAcceptedIssuers()发送出去。这并不是为了提供一定程度的权威。我检查客户端的方式只有他们的公钥,因此没有安全风险。

您只需要非常小心,不要混淆TrustedManagers和SSLContext实例。