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



我正在阅读一个开源 P2P 项目的源代码*,并遇到了根据维基百科的说法,这些代码应该使应用程序完全容易受到中间人攻击。

至少如果javax.net.ssl.X509TrustManager.getAcceptableIssuers()将空数组视为"信任任何"而不是"不信任任何"。

可能会这样做,因为据它所知,您充当具有匿名客户端的服务器,而不是加密的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仅存储本地节点的密钥,而不存储任何远程密钥。

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

此代码是否对中间人开放?

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

最新更新