【问题标题】:Simulate a SSL client in java在 java 中模拟 SSL 客户端
【发布时间】:2023-04-04 07:15:01
【问题描述】:

我有一个关于 java 中的 ssl 客户端的问题。 在浏览器的情况下,客户端 hello 请求启动时包含它支持的密码套件、版本号等,并且服务器以具有将用于此会话的密码套件的服务器 hello 进行响应。

我认为此时会创建一个会话 (jsessionId)(服务器 hello),如果客户端 hello 中不存在会话(这意味着 jsessionId 被发送到未受保护的客户端(?))

此过程完成后,浏览器会根据需要发出 https 请求,并且浏览器会使用服务器 hello 中返回的密码套件中提到的加密算法对其进行加密。

如果我必须在 java 中执行此操作,我可以使用 SSLSocket 进行握手并在 addHandshakeCompletedListener 方法中关联一个处理程序。

所以,一旦握手完成,控制权就交给addHandshakeCompletedListener回调方法。

所以,如果现在我需要发出 ssl 请求,我将不得不使用 HttpsURLConnection (?) 并创建一个请求。

我的问题是 - HttpsURLConnection 如何知道加密算法然后使用它进行加密?

我可以自己使用密码套件中的加密算法对其进行加密,然后通过正常的 http 连接 (HttpURLConnection (?)) 发布它。它会起作用吗?

我知道这是一个复杂的结构 - 我们必须计算 mac,然后在加密数据之前附加。 HttpsURLConnection 会做这一切吗?

会话如何维护? HttpsURLConnection怎么知道这个连接已经发起,握手过程已经完成?

我无法关联所有这些?任何帮助,将不胜感激!如果可能,请举例说明。

【问题讨论】:

  • jsessionID 是上层实体,超出 ssl 握手(服务器问候)。它在 http(s) 层但不在套接字层 (ssl)
  • 您的标题是“用 Java 模拟 SSL 客户端”。这是什么意思?为什么要模拟 Java 已经可以做的事情?

标签: java ssl


【解决方案1】:

我有一个关于 java 中的 ssl 客户端的问题。在浏览器的情况下,客户端 hello 请求启动时包含它支持的密码套件、版本号等,并且服务器以具有将用于此会话的密码套件的服务器 hello 进行响应。

正确。

如果客户端 hello 中不存在会话 (jsessionId),我认为此时会创建一个会话 (jsessionId)(服务器 hello)(这意味着 jsessionId 被发送到未受保护的客户端(?))

没有。这是 HTTPS 的一部分,而不是 SSL,它发生在 SSL 握手完成之后。

此过程完成后,浏览器会根据需要发出 https 请求,并且浏览器会使用服务器 hello 中返回的密码套件中提到的加密算法对其进行加密。

正确。

如果我必须在 java 中执行此操作,我可以使用 SSLSocket 进行握手并在 addHandshakeCompletedListener 方法中关联一个处理程序。

如果您必须在 Java 中使用 HTTPS,您只需要一个 HttpsURLConnection。您也不需要SSLSocket

所以,一旦握手完成,控制权就交给 addHandshakeCompletedListener 回调方法。

这只是为了验证peer身份,HttpsURLConnection不会发生这种情况。

所以,如果现在我需要发出 ssl 请求,我将不得不使用 HttpsURLConnection (?) 并创建一个请求。

这是您应该开始的地方。超过这一点的一切都与你无关。

我的问题是 - HttpsURLConnection 如何知道加密算法然后使用它进行加密?

它没有。它在内部使用 SSLSocket 来完成所有这些工作。

我可以自己使用密码套件中的加密算法对其进行加密,然后通过普通的 http 连接 (HttpURLConnection (?)) 发布它。它会起作用吗?

没有,也没有。这些都不是必需的。一切都为你完成。

我知道这是一个复杂的结构——我们必须计算 mac,然后在加密数据之前附加。 HttpsURLConnection 能做到这一切吗?

不,SSLSocket 做到了。

会话如何维护?

哪个会话?有两种:SSL 会话和 HTTPS 会话。 SSL 会话由底层 SSLContext 维护,HTTPS 会话由服务器通过 jsessionid cookie 维护。

HttpsURLConnection 怎么知道这个连接已经发起,握手过程已经完成?

因为它使用了SSLSocket 来这样做。

我无法关联所有这些?任何帮助,将不胜感激!如果可能,请举例说明。

太宽泛了。

【讨论】:

    【解决方案2】:

    所以,如果现在我需要发出 ssl 请求,我将不得不使用 HttpsURLConnection (?) 并创建一个请求。

    我的问题是 - HttpsURLConnection 如何知道加密 算法然后用那个加密?

    是的,您必须使用 HttpsURLConnection。但你不必明确地这样做。 new URL("https://google.pl").openConnection(); 已经足够了。

    在 Server Hello 中,服务器宣布它可以接受的加密。所有加密方法都必须“宣布”自己,以便服务器知道如何解释它们。 因此,当您启动连接时,服务器会说明它可以处理的内容,客户端选择其中一个密码器并使用它对数据进行密码术。在连接开始时,客户端宣布它将使用什么套件。

    此信息可以公开,这不是问题,这是以明文形式发送的。关键是,在服务器中的客户端之间以私有方式交换对称密钥,因此可以使用该密钥对其余通信进行加密。

    会话如何维护? HttpsURLConnection 怎么知道这个 连接已经启动并且握手过程已经 已经完成了吗?

    那么 SSL 代表安全套接字层。这意味着数据传输和接收是加密的,在原始套接字(流)级别解密;您可以打开 SSL 连接以点对点传输数据,而不仅仅是通过 Https

    没有“会话”。只要你打开一个连接,你就会得到 2 个流。输入和输出。只要这些是打开的,您就可以写入数据或从中读取数据。一旦它们关闭,您将不得不启动另一个连接。

    每个 Http 请求都是一个新连接(除非发送 Keep-Alive)。例如,JsessionId 或 php 的 sessionid 用于标识您是之前发出请求的同一个客户端,因此它可以“模拟”持续连接。

    【讨论】:

    • 我假设服务器/客户端 hello 事务是与实际请求不同的连接,并且由于它是在 http 之上构建的,因此它是无状态的。那么,第一个请求如何知道客户端/服务器 hello 中协商的内容?
    • 这是你不懂的。它不是 http 的 SSL 构建 otop,但 https 是在 SSL 之上构建的。 Hanshake 在套接字层 (ssl) 上。在通过安全套接字建立安全连接后发送实际的 http 数据(请求)。所以基本上单个请求是 -> 连接 -> 做 ssl 握手 -> 交换密钥 -> 建立安全通道 -> HTTPS 传输请求数据 -> 接收响应。
    • 至于“那么,第一个请求如何知道客户端/服务器 hello 中协商的内容” - 它不知道。这是与所有握手和其他东西的全新连接(阅读我的回复)。
    • 好的 :( ,所以一旦服务器决定了一个密码套件并将其发送给客户端,当它从客户端获得下一个请求(比如资源)时,服务器如何知道适合使用哪个密码?每个请求中是否包含密码套件或服务器将其与会话相关联并每次都从那里获取?
    • 服务器对客户端说 - 嘿,我可以接受密码 X、Y、Z,仅此而已。然后客户响应 - 好的,我将使用 Y ciper。然后客户端开始传输数据。没有办法在请求之间使用不同的密码。服务器应用程序使用会话标识符(jsession id、phpsession id)来识别多个连接和请求并将其“配对”或“分组”到单个逻辑会话中(或将它们作为单个连续连接来威胁。
    猜你喜欢
    • 2017-10-04
    • 2022-10-23
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多