是否可以删除Java中SSL握手的扩展部分?

问题描述 投票:0回答:2

我尝试使用 https 连接到一个旧版 Cisco IPS 服务器。问题是该服务器仅接受特定条件下的握手:

版本必须为 TLSv1.0,密码套件必须为 SSL_RSA_WITH_RC4_128_MD5 或 SSL_RSA_WITH_RC4_128_SHA,且不得有任何扩展名。

我实现了一个手工制作的“ClientHello”,它将以下信息作为握手发送(wireshark 输出):

Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
    Content Type: Handshake (22)
    Version: TLS 1.0 (0x0301)
    Length: 45
    Handshake Protocol: Client Hello
        Handshake Type: Client Hello (1)
        Length: 41
        Version: TLS 1.0 (0x0301)
        Random
        Session ID Length: 0
        Cipher Suites Length: 2
        Cipher Suites (1 suite)
        Compression Methods Length: 1
        Compression Methods (1 method)

服务器发回ServerHello消息。

现在我想使用 Java 的 SSL 实现来发送“完全相同”的 ClientHello。代码如下: System.setProperty("https.protocols", "TLSv1"); System.setProperty("javax.net.debug", "ssl:handshake"); SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket socket = (SSLSocket) factory.createSocket("ips-server", 443); socket.setEnabledProtocols(new String[] {"TLSv1"}); socket.setEnabledCipherSuites(new String[] {"SSL_RSA_WITH_RC4_128_MD5"}); socket.startHandshake();

 产生以下握手: 

Secure Sockets Layer TLSv1.2 Record Layer: Handshake Protocol: Client Hello Content Type: Handshake (22) Version: TLS 1.0 (0x0301) Length: 52 Handshake Protocol: Client Hello Handshake Type: Client Hello (1) Length: 48 Version: TLS 1.0 (0x0301) Random Session ID Length: 0 Cipher Suites Length: 2 Cipher Suites (1 suite) Compression Methods Length: 1 Compression Methods (1 method) Extensions Length: 5 Extension: renegotiation_info Type: renegotiation_info (0xff01) Length: 1 Renegotiation Info extension

这会导致服务器发回以下数据包:

TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)

是否可以让Java
not

发送数据包的“扩展”部分?

java ssl https handshake jsse
2个回答
1
投票

System.setProperty("https.protocols", "TLSv1,SSLv2Hello");

我使用以下代码连接到服务器:

SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[] { new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }, new SecureRandom()); SSLSocketFactory socketFactory = sslContext.getSocketFactory(); HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory); HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection(); conn.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String string, SSLSession ssls) { return true; } });

编辑

更多解释 - @EJP 提到这段代码没有回答标题中的问题。我编写了一个小测试来显示 SSL 客户端 hello 的扩展部分是否被删除,作为将客户端 hello 更改为 SSLv2 的副作用。 public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException, IOException { System.setProperty("https.protocols", "TLSv1,SSLv2Hello"); String url = "https://www.google.com"; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] xcs, String string) { } @Override public void checkServerTrusted(X509Certificate[] xcs, String string) { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }}, new SecureRandom()); SSLSocketFactory socketFactory = sslContext.getSocketFactory(); HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory); HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection(); conn.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String string, SSLSession ssls) { return true; } }); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); Stream<String> lines = br.lines(); lines.forEach(l -> { System.out.println(l);}); }

如果我运行这个程序,这就是我在wireshark中得到的结果: 

enter image description here 如果我注释掉 SSLv2Client 部分,我会得到:

enter image description here 很明显,这实现了我一直在寻找的东西:删除 SSL 握手的扩展部分。也许这不是最好的方法,正如 @EJP 提到的,引入了很多安全漏洞(这里不是我关心的,因为我的 CISCO IPS 服务器是本地的,我只想连接到它,无论安全与否),但我不能找到任何其他方法来做到这一点。

自从

0
投票
可用以来,可以用 Java 控制扩展。请参阅

“配置默认扩展”了解更多详细信息。

© www.soinside.com 2019 - 2024. All rights reserved.