【问题标题】:SSL connection using Java standalone app使用 Java 独立应用程序的 SSL 连接
【发布时间】:2010-05-19 21:03:02
【问题描述】:

我创建了一个独立的可执行 JAR 程序,它需要通过 SSL 连接发送私人信息。
我无法使用证书建立 SSL 连接。得到这个:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path `building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target`

所以我在某处发现了一些代码,它创建了一个不验证证书链的信任管理器:

// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(
                    java.security.cert.X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(
                    java.security.cert.X509Certificate[] certs, String authType) {
                }
            }
        };

成功了,我能够在没有任何证书的情况下建立 SSL 连接。

我担心在交换私人信息时数据是否仍会被加密。 这是一个执行 JAR 文件,客户端将下载到他们的计算机上。

那么这个案例真的需要证书吗?

【问题讨论】:

    标签: java encryption ssl


    【解决方案1】:

    它仍然是加密的,但不值得信赖。最好改为修复证书验证问题。

    从本质上讲,SSL 提供了加密和信任机制。您正在绕过信任部分,因此消息仍将被加密,但容易被拦截或窥探,例如使用中间人攻击。 MITM 可以拦截请求,并使用完全不同的证书完成 SSL 握手。他们可以选择将您的消息转发到预期的服务器并返回,因此您永远不会知道消息被拦截了。

    您应该考虑下载服务器证书并将其放入可在运行时加载的信任库。

    见keytool。 keytool 可执行文件与 JDK 捆绑在一起,您可以使用此命令行工具创建“密钥库”(在本例中称为“信任库”),并将证书导入其中。

    有很多方法可以告诉 Java 使用密钥库,您的选择取决于您用于建立 SSL 连接的库等。 一种方法是使用启动选项,例如:

    -Djavax.net.ssl.trustStore=mySrvKeystore -Djavax.net.ssl.trustStorePassword=123456

    最好用谷歌搜索“keystore java”加上你的库名(如果你正在使用的话)

    HTH

    【讨论】:

    • 感谢您的回复,非常有帮助。因此,由于此 JAR 将下载/安装到客户端的计算机中,我想有一种方法可以下载证书并将其保存在密钥库中。所以证书需要下载并存储在客户端计算机中?为此,我是否必须使用本机代码在客户端计算机中执行该 keytool 命令?
    • 不,您只需在自己的计算机上执行一次 keytool,然后将密钥库(通常是 ..jks 文件)与您的应用程序一起交付。我很确定您可以将密钥库包装到您的 jar 文件中,并通过类路径引用它……抱歉,Java 的 ssl 客户端实现不容易理解,需要一些阅读和实践才能与之相处好的...
    • 非常感谢。现在我对我必须做的事情有了清晰的认识。
    • '如果拦截方有必要的私钥来解密消息'。这是不正确的。没有私钥来解密消息 - 在对等方之间动态协商的会话密钥。所谓的 TrustManager 的问题在于它会阻止您知道您正在与谁交谈。因此,您可以与任何人进行完全安全的通信。没有身份验证,SSL 是不安全的。请参阅 RFC 2246。
    • @amir75:SSL 使用会话密钥。数据未使用私钥加密。时期。在只有服务器具有证书的情况下,您所描述的甚至是不可能的。 Verisign 链接充其量是误导,最坏的情况是错误的。这里的权威是 RFC2246,而不是 Verisign 的营销材料。
    【解决方案2】:

    使用这样的信任管理器(或匿名密码套件),连接仍将被加密(假设您没有启用使用空密码的密码套件,默认情况下不应启用)。

    但是,客户端不知道它正在与哪个实体交换秘密信息:它可能是中间人攻击者。

    加密是不够的:你需要知道你在和谁说话。客户需要验证:

    • 它相信服务器证书是真实的(这是信任管理器的目的,但不是这个特定的实现,因为它从不拒绝任何东西),
    • 此证书对客户端要联系的主机名有效。

    【讨论】:

      猜你喜欢
      • 2013-09-22
      • 1970-01-01
      • 2014-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-18
      • 2014-01-29
      • 1970-01-01
      相关资源
      最近更新 更多