在查看SecureSocket
的文档时,我发现方法created
/ secure
/ connect
中有一个名为secureServer
的参数。
答案 0 :(得分:3)
过去,未加密的应用程序协议通常会分配自己的端口(例如80
为http
,25
为smtp
。
ALPN :现在大多数流量都是通过TLS加密的,TLS是一种安全的传输协议。任何应用程序协议都可以使用它不是为应用程序协议使用新的端口号,而是提供了不同的解决方案:TLS支持称为 ALPN(应用程序级协议协商)的扩展,它允许客户端/服务器告知对等方它们支持哪些协议,他们更喜欢什么(可能会回退到由端口号推断出的协议 - 这对于向后兼容性非常有用)
(附注:还有一个前驱TLS扩展名为NPN" Next Protocol Negotiation"服务于类似目的,但由于各种原因而被弃用)
最常见的用例是http / 2 :服务器在端口443
上收听并提供发言http/1.1
,http/2
并让我们说spdy
。浏览器将与服务器端口443
建立TCP连接,并让服务器知道它支持哪些协议。然后,服务器将选择要说出的协议(基于客户端发送的列表以及服务器应用程序支持的内容)。为了向后兼容,如果没有协商协议,客户端/浏览器将回退到http/1.1
。
Negogiation&优先级有3种情况:
客户端或服务器不支持ALPN扩展:没有协议被忽视
客户端和服务器支持ALPN但没有通用协议:没有协议被新消息
客户端和服务器支持ALPN,并且有一个或多个协议都支持:采用优先级最高的协议。
Dart支持:Dart在不久前添加了对ALPN的支持,并通过可选的命名supportedProtocols
参数将其公开给
一旦建立了TLS连接,两端都将能够通过SecureSocket.selectedProtocol查看否定的协议。如果对等方不支持ALPN TLS扩展或没有通用协议,则selectedProtocol
将为null
。
supportedProtocols
中的协议以递减优先级指定(列表中第一个在服务器/客户端之间通用的协议)。
ALPN标识符协议标识符的含义没有实际限制。您的应用程序可以使用自己的。虽然对于公共协议,通常RFC会建议使用哪些标识符,例如RFC 7540中指定的section 3.1:
"字符串" h2"标识HTTP / 2使用传输层安全性(TLS)"
的协议亲自检查:如果您非常好奇,可以使用网络数据包检查程序(如较新版本的wireshark)来检查TLS流量并查看提供的ALPN协议。< / p>
答案 1 :(得分:3)
这是什么?
客户端支持进行安全通信的协议列表
有哪些可能的值?
以斜杠分隔的协议和版本的名称(例如"http/1.1"
)
订单重要吗?
是。优先级按降序设置
一些解释:
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://tools.ietf.org/html/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 7301(ALPN
说明):
"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.
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
&#34;识别序列&#34;是ASCII字节的协议标识符。它是通过套接字在协商阶段发送的原始数据。
有趣的事实:在Dart中,SecurityContext._protocolsToLengthEncoding
方法将协议标识符从字符串编码为字节。
希望这有帮助!