zoukankan      html  css  js  c++  java
  • rfc2818 --- HTTP Over TLS

    协议链接

    本协议描述了如何使用TLS来对Internet上的HTTP进行安全加固。

    2.1. Connection Initiation(链接初始化)

    HTTP client同时也作为TLS client(后续统一称为client)。在建立链接的时候,由client初始化TCP链接,并发出TLS ClientHello报文来开始TLS协商。当TLS协商完成后,client可以初始化首个HTTP请求,所有HTTP数据都被标记为TLS"application data"。

    2.2. Connection Closure(链接结束)

    TLS提供了安全关闭链接的方式,当client/server接收到一个有效的closure alert(rfc5246 7.2.1章节)报文时,认为该链接上不会接收到后续数据,TLS在结束链接前必须交换closure alert。但在实现中,当一端发送了closure alert之后,它可能会直接关闭链接而无需等待对端回复closure alert(此时上层应用应该接收了所有需要的数据),这种实现称之为"incomplete close",该实现可能用于重用tls session的场景。

    RFC2246中描述了一种场景,在接受到首个closure alert之前接收到了(premature close ,如底层tcp断链)断链请求,此时不能重用该session。这种情况下需要处理HTTP数据可能被截断的问题。

    2.2.1. Client Behavior(客户端行为)

    由于HTTP通过执行关闭连接操作来表示数据传输的正常终止,因此当client遇到premature close的情况时,必须将其视为一种错误行为并假设已经接收到的数据可能会被截断。在一些情况下,HTTP协议允许client判断是否发生了数据截断,当接收到一个完整的数据回复时,client可能会"[be] strict when sending and tolerant when receiving" [RFC1958]容忍这些错误。如下两种情景需要特别注意:

    • HTTP响应中不存在Content-Length header字段:这种情况下,由于数据长度字段是由产生premature close的server填写的,无法区分该close是否是攻击者发出的
    • 在接收完所有数据前,HTTP响应中存在合法的Content-Length header字段:由于TLS没有提供文档层面的保护,因此无法判断是否是server端误算了Content-Length还是攻击者截断了数据

    (如上两种情况用于处理截断攻击,如果此时http首部不存在Content-Length,该报文是不可信的,且如果报文的Content-Length和实际数据不匹配也是不可信的。但接收到一个有效的报文,即Content-Length与实际数据匹配时,做特殊处理,见下文)

    当client遇到premature close时,如果此时client接收到了Content-Length的数据,则认为是链接正常完成。
    client在检测到incomplete close时应该进行优雅恢复,可能会重用TLS session

    Client在结束链接前必须发送closure alert报文
    Client在没有准备好接受更多数据时,可能会选择关闭链接而不等待server回复closure alert,这样会使得server处于incomplete close状态

    2.2.2. Server Behavior(服务端行为)

    RFC 2616 允许HTTP client在任意时间关闭链接,并要求server进行优雅恢复。server应该应对client造成的incomplete close,sever也应该重用这种情况下关闭的TLS session。

    在使用非长连接的情况下,server端通常会通过关闭链接来发送数据传输结束信号。当HTTP使用Content-Length时,client端可能已经发送closure alert并断开链接。
    server在关闭链接前必须尝试跟client交互closure alerts。server可能在发送closure alerts之后关闭链接,这样会使得client处于incomplete close状态

    2.3. Port Number(端口号)

    建立链接时,HTTP server期望接收的首数据为Request-Line(rfc2616),TLS server(即http/TLS server)期望接收的首数据为ClientHello。因此HTTP和TLS需要允许在不同的端口上以区分不同的协议类型。当HTTP/TLS允许在TCP/IP之上,默认端口为443。TLS假定仅允许在面向链接的数据流之上。

    2.4. URI Format(URI 格式)

    HTTPS/TLS通过"https"来与"http"协议进行区分

    3. Endpoint Identification
    3.1. Server Identity

    通常HTTP/TLS 请求与URI关联,因此client需要知道server的hostname,并且将其与server Certificate消息中的server identity进行校验,以防止中间人攻击。

    如果client拥有与server identity相关的额外信息,有可能忽略对hostname的校验(如客户端连接的机器的地址和hostname是动态的,但client知道server 提供的证书),在这种情况下,会尽可能减少可接受证书的范围,以防止中间人攻击。特殊场景下,client可能会忽略server的identity,但必须意识到这种行为可能导致的攻击。

    证书中如果subjectAltName(SAN)出现了dNSName,必须将该处定义的内容作为identity,否则使用Common Name字段作为identity。Certification Authorities鼓励使用dNSName。

    如果证书中出现多种类型的identity(如多个dNSName名称,匹配任意一个即可),可能会包含通配符"*",表示可以匹配任意单个域名或域名段。如*.a.com匹配foo.a.com,但不匹配bar.foo.a.com。f*.com匹配foo.com,但不匹配bar.com(即通配符域名证书只匹配同级别的通配域名,不能跨级匹配)

    一些场景下,URI使用IP而非hostname,这种情况下,证书中必须出现iPAddress subjectAltName且必须匹配URI中的IP。
    如果hostname不匹配证书的identity,client端必须通知用户(是否继续连接)或结束链接(给出错误证书提示)。automated client必须记录该错误日志到审计日志(audit log --如linux的审计日志功能)并关闭连接

    在很多情况下,URI的源不可信,此时需要检查server提供的证书的有效性,防止中间人攻击。

    3.2. Client Identity

    通常server并不了解client的identity,因此无法对client进行校验。反之,则应该对client进行校验

  • 相关阅读:
    ShellExecuteEx 函数说明
    npm
    Byte和char
    如何高效阅读一个项目
    C++中慎用malloc
    #ifdef
    string
    C++与C混合编译
    git@github.com: Permission denied (publickey).
    connect to host github.com port 22: Connection refused
  • 原文地址:https://www.cnblogs.com/charlieroro/p/10684112.html
Copyright © 2011-2022 走看看