栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

正确关闭SSLSocket

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

正确关闭SSLSocket

这是我最初的(暂时删除的)答案,但是显然还不够好,因为它很快就被-2了……我想我应该添加更多的解释。

不能关闭SSL /
TLS套接字的一半连接,以使其符合TLS协议(如关闭警报部分所述)。

客户端和服务器必须共享有关连接即将结束的知识,以避免被截断攻击。任何一方均可发起结束消息的交换。

close_notify
此消息通知收件人,发件人将不再通过此连接发送任何消息。如果在没有适当的close_notify消息的情况下终止任何连接,并且会话级别等于警告,则该会话将无法恢复。

任何一方都可以通过发送close_notify警报来发起关闭。关闭警报后收到的任何数据都将被忽略。

要求各方在关闭连接的写端之前发送close_notify警报。要求另一方以自己的close_notify警报响应并立即关闭连接,并丢弃所有未决的写入。关闭的发起方不需要在关闭连接的读取端之前等待响应的close_notify警报。

尽管您可能只想关闭一半的连接(通过

shutdownInput()
/
输入或输出
shutdownOutput()
),但底层TLS层仍需要
close_notify
在真正关闭通信之前发送此数据包,否则,它将被视为截断攻击。

修复非常简单:仅

close()
SSLSocket
s上使用:它不仅会像普通TCP套接字那样关闭连接,而且会根据SSL / TLS规范进行整洁的连接。

编辑附加说明

简短的答案仍然是:use

close()
,您可能还需要从SSL / TLS顶部的协议中找出合适的时机。

(为澄清起见,您实际上想做的是有效的“中间人”(MITM)代理。您需要将客户端配置为信任代理的证书,就像它是服务器一样证书(如果要透明地进行的话)。HTTPS连接如何通过HTTP代理工作是一个不同的问题。)

在您对其他相关问题的一些评论中,我得到的印象是,您认为不返回

-1
就是“破坏了TLS协议”。这实际上与协议无关,而是与API有关:将编程结构(类,方法,函数等)提供给TLS堆栈的(程序员)用户以使用TLS的方式。
SSLSocket
API只是API的一部分,以使程序员能够以类似于plain的方式使用SSL
/ TLS
Socket
。TLS规范根本不涉及套接字。TLS(及其前身,SSL)的构建旨在提供这种抽象,但归根结底
SSLSocket
就是:抽象。符合OOP设计原则,
SSLSocket
继承
Socket
并尝试尽可能地坚持行为
Socket
。但是,由于SSL
/ TLS的工作方式(并且
SSLSocket
有效地位于normal之上
Socket
),因此无法精确映射所有功能。

特别是,从普通TCP套接字到SSL /
TLS套接字的过渡区域不能完全透明地建模。在设计

SSLSocket
类时,必须做出一些任意选择(例如,握手方式):这是在(a)不向
SSLSocket
用户暴露过多的TLS特殊性,(b)使TLS机制起作用和((
c)将所有这些映射到超类(
Socket
)提供的现有接口。这些选择不可避免地会对的功能产生一些影响
SSLSocket
,这就是其Javadoc
API页面包含相对大量文本的原因。
SSLSocket.close()
就API而言,必须遵守的描述
Socket.close()
。在
InputStream
/
OutputStream
从所获得的
SSLSocket
不同于底层平原的
Socket
那个(除非您已将其显式转换),否则可能看不到。

SSLSocket
被设计为尽可能地像平原一样可用
Socket
,并且
InputStream
您获得的设计被设计为与基于文件的输入流尽可能接近。顺便说一下,这不是特定于Java的。甚至C语言中的Unix套接字也与文件描述符和一起使用
read()
。只要您知道它们的局限性,这些抽象就很方便并且在大多数时候都可以使用。

当涉及到时

read()
,即使在C语言中,的概念也
EOF
来自文件结尾终止,但实际上并没有处理文件。TCP套接字的问题在于,虽然您可以检测到远程方在发送时选择了关闭连接,但是
FIN
您却无法检测到它没有发送任何内容(如果没有发送)。从套接字读取任何内容时,无法分辨无效连接和断开连接之间的区别。因此,在进行网络编程时,只能依靠
-1
InputStream
if
读取,但您绝不能完全依靠它来进行读取,否则最终可能会遇到未发布的无效连接。一方正确地关闭半个TCP连接是“礼貌”的(例如,远程方读取
-1
InputStream
或类似的内容(如Java中的有序与异常连接发行版中所述),仅处理这种情况是不够的。这就是为什么TCP之上的协议通常旨在指示何时完成发送数据的原因:例如,SMTP发送
QUIT
(并具有特定的终止符),HTTP 1.1使用
Content-Length
或分块编码。

(顺便说一句,如果您对提供的抽象不满意

SSLSocket
,请尝试
SSLEngine
直接使用。它可能会更难,并且不会改变TLS规范中关于发送的说明
close_notify
。)

通常,对于TCP,您应该在应用协议级别上知道何时停止发送和接收数据(以避免未释放的连接和/或依赖超时错误)。TLS规范中的这句话使TLS成为一个更好的要求,它是对TLS的一个更强的要求:“
要求对方以自己的close_notify警报响应并关闭连接,并立即丢弃所有未决的写入。
”必须通过应用程序协议以某种方式进行同步,否则远程方可能仍然需要写一些东西(尤其是如果您允许使用流水线式的请求/响应)。

如果您要编写的代理用于拦截HTTPS连接(作为MITM),则可以调查请求的内容。即使HTTP请求是通过管道传递的,您也可以计算目标服务器发送的响应数(并通过Content-
Length或块定界符期望它们何时结束)。

但是,您将无法拥有一个完全透明的通用TLS“拦截器”。TLS旨在确保两方之间的传输安全,并且中间没有一方。虽然大多数实现该保护的机制(避免使用MITM)都是通过服务器证书来完成的,但其他一些TLS机制也会成为障碍(关闭警报就是其中之一)。请记住,您实际上是在创建两个不同的TLS连接,考虑到TLS的目的,它们很难合并为一个事实,这不足为奇。

SSLSocket.close()
是关闭的正确方法
SSLSocket
,但是应用程序协议也将帮助您确定何时合适。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/486453.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号