【问题标题】:What are the supported protocols in SecureSocket?SecureSocket 支持哪些协议?
【发布时间】:2017-02-20 19:14:06
【问题描述】:

查看SecureSocket 的文档时,我看到secure/connect/secureServer 方法中有一个参数称为supportedProtocols

  • 这是什么?
  • 可能的值是多少?
  • 顺序重要吗?

【问题讨论】:

    标签: http websocket dart


    【解决方案1】:
    1. 这是什么?

      客户端支持的安全通信协议列表

    2. 可能的值是什么?

      协议和版本的名称以斜线分隔(例如"http/1.1"

    3. 顺序重要吗?

      是的。优先级是按降序设置的

    一些解释:

    TLS 有一个名为ALPN 的扩展名(顾名思义)用于协商用于安全通信的应用层协议。

    ALPN 中,协议使用我上面指定的格式进行标识。

    SecureSocket 实现了TLS,因此必须接收要在ALPN 阶段使用的协议列表参数。

    除非您的服务器和客户端正在实施自定义通信协议,否则我建议您只使用"http/1.1"

    更多信息:

    我可以在 Dart 源中找到传递给 SecureServer 的协议列表的唯一文档是 SecurityContext._protocolsToLengthEncoding (io/security_context.dart:190):

    /// Encodes a set of supported protocols for ALPN/NPN usage.
    ///
    /// The `protocols` list is expected to contain protocols in descending order
    /// of preference.
    ///
    /// See RFC 7301 (https://www.rfc-editor.org/rfc/rfc7301) for the encoding of
    /// `List<String> protocols`:
    ///     opaque ProtocolName<1..2^8-1>;
    ///
    ///     struct {
    ///         ProtocolName protocol_name_list<2..2^16-1>
    ///     } ProtocolNameList;
    ///
    /// The encoding of the opaque `ProtocolName<lower..upper>` vector is
    /// described in RFC 2246: 4.3 Vectors.
    ///
    /// Note: Even though this encoding scheme would allow a total
    /// `ProtocolNameList` length of 65535, this limit cannot be reached. Testing
    /// showed that more than ~ 2^14  bytes will fail to negotiate a protocol.
    /// We will be conservative and support only messages up to (1<<13)-1 bytes.
    

    通过RFC 7301ALPN 描述):

    "ProtocolNameList" contains the list of protocols advertised by the
    client, in descending order of preference.  Protocols are named by
    IANA-registered, opaque, non-empty byte strings, as described further
    in Section 6 ("IANA Considerations") of this document. 
    

    还有section 6

    Protocol:  HTTP/1.1
    Identification Sequence:
       0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31 ("http/1.1")
    Reference:  [RFC7230]
    
    Protocol:  SPDY/1
    Identification Sequence:
       0x73 0x70 0x64 0x79 0x2f 0x31 ("spdy/1")
    Reference:
       http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft1
    
    Protocol:  SPDY/2
    Identification Sequence:
       0x73 0x70 0x64 0x79 0x2f 0x32 ("spdy/2")
    Reference:
       http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2
    

    “标识序列”是 ASCII 字节中的协议标识符。是协商阶段通过socket发送的原始数据。

    有趣的事实:在 Dart 中,SecurityContext._protocolsToLengthEncoding 方法将协议标识符从字符串编码为字节。

    希望这有帮助!

    【讨论】:

      【解决方案2】:

      历史上未加密的应用程序协议通常分配有自己的端口(例如,80 用于http25 用于smtp)。

      ALPN:现在大多数流量都是通过 TLS 加密的,这是一种安全的传输协议。任何应用程序协议都可以使用它。除了为应用程序协议使用新的端口号之外,还可以使用不同的解决方案:TLS 支持称为 ALPN(应用程序级协议协商) 的扩展,它允许客户端/服务器告诉对等方他们支持哪些协议和他们喜欢什么(可能回退到由端口号推断的协议——这对向后兼容很有好处)

      (旁注:还有一个称为 NPN“下一个协议协商”的前身 TLS 扩展,用于类似目的,但由于各种原因已被弃用)

      最常见的用例是 http/2:服务器侦听端口 443 并提供说 http/1.1http/2 和假设为 spdy。浏览器将与服务器端口443 建立 TCP 连接,让服务器知道它支持哪些协议。然后服务器将选择使用哪个协议(基于客户端发送的列表和服务器应用程序支持的内容)。为了向后兼容,如果未协商任何协议,客户端/浏览器将回退到 http/1.1

      协商与优先级有3种情况:

      • 客户端或服务器不支持 ALPN 扩展:未协商任何协议

      • 客户端和服务器支持 ALPN,但没有通用协议:没有新协议

      • 客户端和服务器都支持 ALPN,并且有一个或多个协议都支持:优先级最高的协议。

      Dart 支持:Dart 前段时间添加了对 ALPN 的支持,并通过可选的名为 supportedProtocols 的参数公开它

      一旦建立了 TLS 连接,两端将能够通过SecureSocket.selectedProtocol 看到协商的协议。如果对端不支持 ALPN TLS 扩展或者没有通用协议,那么selectedProtocol 将是null

      supportedProtocols 中的协议以递减的方式指定(将选择列表中服务器/客户端通用的第一个)。

      ALPN 标识符 协议标识符可以是什么并没有真正的限制。您的应用程序可以使用它自己的。虽然对于公共协议,通常 RFC 会推荐使用哪些标识符,例如 RFC 7540section 3.1 中指定:

      “字符串“h2”标识 HTTP/2 使用传输层安全 (TLS) 的协议”

      自行检查:如果您非常好奇,可以使用网络数据包检查器(如 wireshark 的较新版本)检查 TLS 流量并查看提供的 ALPN 协议。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-19
        • 2011-01-06
        • 2013-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多