【问题标题】:Send HTTPS Request using SSL Socket使用 SSL 套接字发送 HTTPS 请求
【发布时间】:2017-12-06 11:41:42
【问题描述】:

您好:我正在尝试制作一个主要使用 JAVA 的小型 HTTPS 客户端程序。

下面是sn-p的代码:

SSLSocket result = (SSLSocket) SSLCont.sslSocketFactory.createSocket(
                    sockfd, "www.facebook.com", 443, false);
result.startHandshake(); 
result.getOutputStream().write("GET / HTTP/1.1\r\nHost: www.facebook.com\r\n\r\n".getBytes());
String  res=my.getData(result.getInputStream());
print(res);

我可以正确打印 Facebook 回复。没有问题。

问题是 - 当我使用“TRAFFIC capture”程序看到流量时,我看到“TLS:TLS Rec Layer-1 HandShake: Client Hello”的以下数据。部分

TLS:TLS Rec Layer-1 HandShake: Client Hello.
. .....ÿÿÿÿ.............ïM©.LoÓ....??ÞÐJd:Ôn..¡.?ÞÐJd:..ªª.....
.E..ë.×@.@.».À¨.eð.$?6.»§.Îç?ç.?P.ý\?-
......¾...º..???v????{3?¯ß.DÅJ.>?÷®ÿ±û*^».8i1...À+À/̨̩À,À0À.À.À
.À..3.9./.5.....s.........www.facebook.com....ÿ.
........................#...............................
..........................

但是当我直接在浏览器中打开网站( www.facebook.com )时,我会看到以下流量:

TLS:TLS Rec Layer-1 HandShake: Client Hello.
. .....ÿÿÿÿ.............ïM©.LoÓ....??ÞÐJd:Ôn..¡.?ÞÐJd:..ªª.....
.E..ë.×@.@.».À¨.eð.$?6.»§.Îç?ç.?P.ý\?-
......¾...º..???v????{3?¯ß.DÅJ.>?÷®ÿ±û*^».8i1...À+À/̨̩À,À0À.À.À
.À..3.9./.5.....s.........www.facebook.com....ÿ.
........................#.........h2.http/1.1...........
..........................

如果我们仔细比较两个流量数据,我们会看到,如果是 Chrome 浏览器生成的流量,我们会看到以下额外的字符串 "..h2.http/1.1...." 最后附加,这表明它是用于 HTTP 并且看起来很完美。

但是这个字符串并没有附加到我的 java 程序生成的流量中。

您能否告诉我为什么“..h2.http/1.1....”字符串没有出现在我的 java 程序生成的流量中。 如何修改我的java代码,使字符串出现在我的java程序生成的请求流量中。

注意:但是当我使用 java 内置类“HttpsURLConnection”打开该网站时,我看到“..h2.http/1.1....”存在在交通。 此问题适用于所有 HTTPS 网站。

你能告诉我我的 Java 代码中缺少什么吗?

提前谢谢你

【问题讨论】:

    标签: java sockets ssl openssl traffic


    【解决方案1】:

    你能告诉我为什么“..h2.http/1.1....”字符串没有出现在我的 java 程序生成的流量中。

    首先,在分析二进制协议(如 TLS 一样)时,将其视为文本并不是一个好主意。如果您改为使用 Wireshark 查看流量并深入研究 TLS 握手,您会发现客户端使用 ALPN 向服务器表明它确实支持“h2”(HTTP/2)和“http/1.1” (HTTP/1.1)。支持 HTTP/2 的服务器可能会使用它作为连接协议,而不是 HTTP/1.1,因为 HTTP/2 更有效。

    如何修改我的java代码,使字符串出现在我的java程序生成的请求流量中。

    除非您能够使用 HTTP/2 协议与服务器正确通信,否则您不想告诉服务器您可以执行 HTTP/2,即您不想使用 ALPN 添加此信息。鉴于您刚刚成功发送了一个 HTTP 请求但未能正确处理响应(您希望服务器在响应后关闭连接,尽管您允许服务器通过使用 HTTP/ 隐式启用 HTTP keep-alive 来保持连接打开) 1.1) 我怀疑你是否可以使用更复杂的 HTTP/2 协议。

    【讨论】:

    • 感谢您的回复。这一行“result.startHandshake();”正在生成该流量。这是客户端对服务器的第一次调用。此时它对服务器协议等一无所知。我想知道为什么 REQUEST DATA 在两种情况下都不同。我应该在调用 result.startHandshake() 之前设置任何参数吗?谢谢
    • 当我使用 HttpsURLConnection 类时,它正在生成该字符串。它发生在第一次请求握手呼叫中。这意味着即使我尝试连接到 FTP 或任何其他假服务器,我也会看到相同的请求数据。
    • 但问题是为什么我的调用 result.startHandshake() 没有像 Browser 或 HttpsURLConnection 那样生成请求。可能我需要在调用 startHandshake(); 之前再写一些代码;请帮忙。
    • 是的。我明白。您能告诉我如何在客户端问候/握手中添加该信息 HTTP 1.1 或 HTTP 2。到目前为止,我还没有看到任何方法。我知道我只能设置 CipherSuites 等谢谢
    • @poorcoder:有 Java 9 ALPN 支持,请参阅de.slideshare.net/martintoshev/… slides 22..25。对于旧版本的 Java,请参阅 unrestful.io/2015/10/09/alpn-java.html
    猜你喜欢
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 2020-11-27
    • 2013-05-14
    • 2011-06-10
    相关资源
    最近更新 更多