【问题标题】:Validation of a certificate chain when opening a SSLSocket in Java在 Java 中打开 SSLSocket 时验证证书链
【发布时间】:2017-06-07 01:22:30
【问题描述】:

我的设置

我的目标是与 FTP 服务器建立 SSL/TLS 安全连接(显式)。 相应的根 CA 证书存储在名为 truststore.jks 的信任库中。 在AUTH TLScommand 之后,我使用以下代码构建 SSLSocket。

public SSLSocket enterSecureMode(Socket s) throws Exception {
        KeyStore truststore = KeyStore.getInstance("JKS");
        truststore.load(Files.newInputStream(Paths.get("truststore.jks")), "mypass".toCharArray());

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(truststore);

        SSLContext sCon = SSLContext.getInstance("TLS");
        sCon.init(null, tmf.getTrustManagers(), null);

        SSLSocketFactory sslSocketFactory = sCon.getSocketFactory();
        return (SSLSocket) sslSocketFactory.createSocket(s, "<HOSTNAME>", 21, true);
}

代码本身运行良好,我收到了一个安全的 Socket-Connection,但我想知道这是否可以承受诸如 MITM 之类的攻击。我的意思是该程序会发现有人试图“给我一个假证书”。 因此,如果一些更有经验的 SSL 网络程序员可以启发我,我会很高兴:D

【问题讨论】:

    标签: java ssl


    【解决方案1】:

    这就足够了。攻击者必须提供由根 CA 签名的证书。但是你不需要所有这些代码:你只需要

    System.setProperty("javax.net.ssl.trustStore", "truststore.jks");
    SSLContext sCon = SSLContext.getDefault();
    SSLSocketFactory sslSocketFactory = sCon.getSocketFactory();
    return (SSLSocket) sslSocketFactory.createSocket(s, "<HOSTNAME>", 21, true)
    

    如果你想完全偏执,在创建SSLSocket 之后,你可以获得SSLSession,然后是对等证书链,并确保第零项与确切的服务器证书完全匹配,但这一步大多省略.

    【讨论】:

    • 假设我对安全性持偏执态度(主要是因为我希望为我的程序/数据提供最大程度的保护)。我是否必须存储服务器证书的指纹并在启动 SSL 连接时检查它们是否匹配?
    • 是的,您可以这样做,或者确实存储整个证书并按位进行比较。但是,如果您执行了其中任何一项操作,则必须在每次到期时对其进行更新。如果它由正确的根 CA 签名并具有相同的主题可分辨名称,根 CA 有义务对其进行验证,则它可以被信任。
    猜你喜欢
    • 1970-01-01
    • 2012-09-28
    • 2015-07-09
    • 2017-08-15
    • 1970-01-01
    • 2022-08-19
    • 2012-06-23
    • 2013-01-28
    • 1970-01-01
    相关资源
    最近更新 更多