这是接受自签名证书的有效方法吗?

发布于 2024-12-09 13:42:37 字数 867 浏览 0 评论 0原文

我编写此代码是为了接受来自服务器的所有自签名证书:

private TrustManager[] createTrustManager() {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                if (!chain[0].getIssuerDN().equals(chain[0].getSubjectDN())) {
                    throw new CertificateException("This is not a self-signed certificate");
                }
            }

            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // leave blank to trust every client
            }
        }};
        return trustAllCerts;
    }

这是一种有效且充分的方法吗?

I wrote this code to accept all self-signed certificates from a server:

private TrustManager[] createTrustManager() {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                if (!chain[0].getIssuerDN().equals(chain[0].getSubjectDN())) {
                    throw new CertificateException("This is not a self-signed certificate");
                }
            }

            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // leave blank to trust every client
            }
        }};
        return trustAllCerts;
    }

Is this a valid and sufficient approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

走过海棠暮 2024-12-16 13:42:37

尽管它完成了它的工作,但您的方法基本上否定了正确的 PKI 的目的。如果您盲目信任任何自签名证书,那么使用 TLS 根本没有任何意义 - 任何人都可以创建可通过您的 TrustManager 的自签名证书。

因此,如果您想要安全,那么您应该首先找出您的客户端应用程序将与哪些服务器通信,然后获取链接到这些服务的 TLS 服务器证书(在您的场景中,每个它们是自签名的,因此您无需关心中间证书)。

现在,使用这些证书,您创建一个 JKS“信任存储”文件并将证书放入其中 - 这是您要信任的证书集,未包含在此文件中的证书将被拒绝。要创建 JKS 文件,您可以使用 Java 的 keytool 命令,或者您可以使用 KeyStore API 以编程方式执行此操作。

最后,您将创建供 HttpClient 使用的 SSLContext,并使用如下创建的 TrustManagerinit 它:

KeyStore ks = KeyStore.getInstance("JKS");
ks.load(fin, pwd);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(ks);

其中fin是您的“信任存储”的InputStreampwd是您用于加密它的密码。默认的 TrustManager 实现让您只需要使用一组受信任的证书,其余的都会为您处理。

Although it does its job, your approach basically denies the purpose of a proper PKI. If you blindly trust any self-signed certificate, then there is no point in using TLS at all - anyone can create a self-signed certificate that would pass your TrustManager.

So, if you want to be secure, then you should first find out which servers your client application will be communicating with and then get the TLS server certificates that are linked to those services (in your scenario each of them is self-signed, so you don't need to care about intermediate certificates).

Now, using these certificates, you create a JKS "trust store" file and put the certificates in it - this is the set of certificates you are going to trust, certificates not contained in this file will be rejected. To create a JKS file you can either use Java's keytool command or you can do it programmatically using the KeyStore API.

Finally you would create the SSLContext to be used by your HttpClient and init it with a TrustManager created like this:

KeyStore ks = KeyStore.getInstance("JKS");
ks.load(fin, pwd);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(ks);

where fin is the InputStream of your "trust store" and pwd the password you used to encrypt it. The default TrustManager implementation this gives you needs only the set of trusted certificates to work with, the rest is taken care of for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文