配置错误的Java SSLContext容易受到中间人攻击?

时间:2013-09-30 10:46:32

标签: java security ssl

我正在阅读开源P2P项目*的源代码,并且遇到的代码应该使应用程序完全容易受到中间人攻击 per Wikipedia

至少如果javax.net.ssl.X509TrustManager.getAcceptableIssuers()将空数组视为 Trust Any 而不是 Trust Nothing

它可能会发生这种情况,因为据他所知,你扮演的是一个拥有匿名客户端的服务器,而不是加密的P2P,要求两个同行都是他们所说的人。

class ATrustManager implements X509TrustManager { 
  public ATrustManager() {} 
  public void checkClientTrusted(X509Certificate[] certs, String authType) {} 
  public void checkServerTrusted(X509Certificate[] certs, String authType) {}

  // --- What!? ---
  public X509Certificate[] getAcceptedIssuers() {
    java.security.cert.X509Certificate[0]; 
  }
  // --------------
}

class Blah {
  SomeObject doBlah(...) {  
    // ... various code ...

    char[] password = "password".toCharArray();         
    KeyStore keystore = KeyStore.getInstance("JKS");
    keystore.load(FileInputStream("app.keys"), password);
    KeyManagerFactory aKeyManagerFactory =
        KeyManagerFactory.getInstance("SunX509");   
    aKeyManagerFactory.init(keystore, password);
    KeyManager[] aKeyManager = aKeyManagerFactory.getKeyManagers();
    TrustManager[] aTrustManager = new TrustManager[] { new ATrustManager() };
    SSLContext sslcontext = SSLContext.getInstance("SSL");
    sslcontext.init(aKeyManager, aTrustManager, null);

    SSLSocketFactory socketFactory = sslcontext.getSocketFactory();
    Socket socket = socketFactory.createSocket(hostname, port);
    OutputStream out = socket.getOutputStream();

    // ... various code ...     
}

我的问题:此代码是否适用于中间人?如果是这样,我应该让项目了解它。

注意:

  • 如果远程节点的公钥未知,则应用程序不会删除代码中的其他位置的连接。我查了一下。
  • app.keys仅存储本地节点的密钥,而不存储任何远程密钥。

*匿名源代码以保护有罪。

1 个答案:

答案 0 :(得分:3)

  

此代码是否适用于中间人?

是的。您绝对接受任何SSL证书,无论它是否有效,由受信任的CA签名等,以及它是否是您尝试联系的对等方的证书。永远不要在生产中部署此代码,这意味着它根本不应该编写,除非您喜欢测试不是您将要在生产中部署的部署,除非您喜欢接受代码泄漏等风险进入生产环境,后果严重不安全。