Independent Submission                                     M. Thornburgh
Request for Comments: 7425                                         Adobe
Category: Informational                                    December 2014
ISSN: 2070-1721
        
Independent Submission                                     M. Thornburgh
Request for Comments: 7425                                         Adobe
Category: Informational                                    December 2014
ISSN: 2070-1721
        

Adobe's RTMFP Profile for Flash Communication

Adobe用于Flash通信的RTMFP配置文件

Abstract

摘要

This memo describes how to use Adobe's Secure Real-Time Media Flow Protocol (RTMFP) to transport the video, audio, and data messages of Adobe Flash platform communications. Aspects of this application profile include cryptographic methods and data formats, flow metadata formats, and protocol details for client-server and peer-to-peer communication.

本备忘录描述了如何使用Adobe的安全实时媒体流协议(RTMFP)传输Adobe Flash platform communications的视频、音频和数据消息。此应用程序配置文件的各个方面包括加密方法和数据格式、流元数据格式以及客户端-服务器和对等通信的协议详细信息。

Status of This Memo

关于下段备忘

This document is not an Internet Standards Track specification; it is published for informational purposes.

本文件不是互联网标准跟踪规范;它是为了提供信息而发布的。

This is a contribution to the RFC Series, independently of any other RFC stream. The RFC Editor has chosen to publish this document at its discretion and makes no statement about its value for implementation or deployment. Documents approved for publication by the RFC Editor are not a candidate for any level of Internet Standard; see Section 2 of RFC 5741.

这是对RFC系列的贡献,独立于任何其他RFC流。RFC编辑器已选择自行发布此文档,并且未声明其对实现或部署的价值。RFC编辑批准发布的文件不适用于任何级别的互联网标准;见RFC 5741第2节。

Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc7425.

有关本文件当前状态、任何勘误表以及如何提供反馈的信息,请访问http://www.rfc-editor.org/info/rfc7425.

Copyright Notice

版权公告

Copyright (c) 2014 IETF Trust and the persons identified as the document authors. All rights reserved.

版权所有(c)2014 IETF信托基金和确定为文件作者的人员。版权所有。

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document.

本文件受BCP 78和IETF信托有关IETF文件的法律规定的约束(http://trustee.ietf.org/license-info)自本文件出版之日起生效。请仔细阅读这些文件,因为它们描述了您对本文件的权利和限制。

This document may not be modified, and derivative works of it may not be created, except to format it for publication as an RFC or to translate it into languages other than English.

不得修改本文件,也不得创建其衍生作品,除非将其格式化为RFC出版或将其翻译为英语以外的其他语言。

Table of Contents

目录

   1. Introduction ....................................................3
   2. Terminology .....................................................4
   3. Common Syntax Elements ..........................................4
   4. Cryptography Profile ............................................5
      4.1. Default Session Key ........................................5
      4.2. Diffie-Hellman Groups ......................................6
      4.3. Certificates ...............................................6
           4.3.1. Format ..............................................6
           4.3.2. Fingerprint .........................................7
           4.3.3. Options .............................................7
                  4.3.3.1. Hostname ...................................8
                  4.3.3.2. Accepts Ancillary Data .....................8
                  4.3.3.3. Extra Randomness ...........................8
                  4.3.3.4. Supported Ephemeral Diffie-Hellman Group ...9
                  4.3.3.5. Static Diffie-Hellman Public Key ...........9
           4.3.4. Authenticity .......................................10
           4.3.5. Signing and Verifying Messages .....................10
                  4.3.5.1. Options ...................................11
                           4.3.5.1.1. Simple Password ................11
           4.3.6. Glare Resolution ...................................13
           4.3.7. Session Override ...................................13
      4.4. Endpoint Discriminators ...................................13
           4.4.1. Format .............................................14
           4.4.2. Options ............................................14
                  4.4.2.1. Required Hostname .........................15
                  4.4.2.2. Ancillary Data ............................15
                  4.4.2.3. Fingerprint ...............................16
           4.4.3. Certificate Selection ..............................16
           4.4.4. Canonical Endpoint Discriminator ...................17
      4.5. Session Keying Components .................................18
           4.5.1. Format .............................................19
           4.5.2. Options ............................................19
                  4.5.2.1. Ephemeral Diffie-Hellman Public Key .......20
                  4.5.2.2. Extra Randomness ..........................20
                  4.5.2.3. Diffie-Hellman Group Select ...............21
                  4.5.2.4. HMAC Negotiation ..........................21
                  4.5.2.5. Session Sequence Number Negotiation .......22
      4.6. Session Key Computation ...................................23
           4.6.1. Public Key Selection ...............................23
                  4.6.1.1. Initiator and Responder Ephemeral .........23
                  4.6.1.2. Initiator Ephemeral and Responder Static ..23
                  4.6.1.3. Initiator Static and Responder Ephemeral ..24
                  4.6.1.4. Initiator and Responder Static ............24
           4.6.2. Diffie-Hellman Shared Secret .......................24
           4.6.3. Packet Encrypt/Decrypt Keys ........................25
           4.6.4. Packet HMAC Send/Receive Keys ......................25
        
   1. Introduction ....................................................3
   2. Terminology .....................................................4
   3. Common Syntax Elements ..........................................4
   4. Cryptography Profile ............................................5
      4.1. Default Session Key ........................................5
      4.2. Diffie-Hellman Groups ......................................6
      4.3. Certificates ...............................................6
           4.3.1. Format ..............................................6
           4.3.2. Fingerprint .........................................7
           4.3.3. Options .............................................7
                  4.3.3.1. Hostname ...................................8
                  4.3.3.2. Accepts Ancillary Data .....................8
                  4.3.3.3. Extra Randomness ...........................8
                  4.3.3.4. Supported Ephemeral Diffie-Hellman Group ...9
                  4.3.3.5. Static Diffie-Hellman Public Key ...........9
           4.3.4. Authenticity .......................................10
           4.3.5. Signing and Verifying Messages .....................10
                  4.3.5.1. Options ...................................11
                           4.3.5.1.1. Simple Password ................11
           4.3.6. Glare Resolution ...................................13
           4.3.7. Session Override ...................................13
      4.4. Endpoint Discriminators ...................................13
           4.4.1. Format .............................................14
           4.4.2. Options ............................................14
                  4.4.2.1. Required Hostname .........................15
                  4.4.2.2. Ancillary Data ............................15
                  4.4.2.3. Fingerprint ...............................16
           4.4.3. Certificate Selection ..............................16
           4.4.4. Canonical Endpoint Discriminator ...................17
      4.5. Session Keying Components .................................18
           4.5.1. Format .............................................19
           4.5.2. Options ............................................19
                  4.5.2.1. Ephemeral Diffie-Hellman Public Key .......20
                  4.5.2.2. Extra Randomness ..........................20
                  4.5.2.3. Diffie-Hellman Group Select ...............21
                  4.5.2.4. HMAC Negotiation ..........................21
                  4.5.2.5. Session Sequence Number Negotiation .......22
      4.6. Session Key Computation ...................................23
           4.6.1. Public Key Selection ...............................23
                  4.6.1.1. Initiator and Responder Ephemeral .........23
                  4.6.1.2. Initiator Ephemeral and Responder Static ..23
                  4.6.1.3. Initiator Static and Responder Ephemeral ..24
                  4.6.1.4. Initiator and Responder Static ............24
           4.6.2. Diffie-Hellman Shared Secret .......................24
           4.6.3. Packet Encrypt/Decrypt Keys ........................25
           4.6.4. Packet HMAC Send/Receive Keys ......................25
        
           4.6.5. Session Nonces .....................................26
           4.6.6. Session Sequence Number ............................26
      4.7. Packet Encryption .........................................27
           4.7.1. Cipher .............................................27
           4.7.2. Format .............................................27
           4.7.3. Verification .......................................29
                  4.7.3.1. Simple Checksum ...........................30
                  4.7.3.2. HMAC ......................................30
                  4.7.3.3. Session Sequence Number ...................31
   5. Flash Communication ............................................31
      5.1. RTMP Messages .............................................31
           5.1.1. Flow Metadata ......................................32
           5.1.2. Message Mapping ....................................34
      5.2. Flow Synchronization ......................................35
      5.3. Client-to-Server Connection ...............................36
           5.3.1. Connecting .........................................36
           5.3.2. Server-to-Client Return Control Flow ...............37
           5.3.3. setPeerInfo Command ................................37
           5.3.4. Set Keepalive Timers Command .......................39
           5.3.5. Additional Flows for Streams .......................40
                  5.3.5.1. To Server .................................40
                  5.3.5.2. From Server ...............................40
                  5.3.5.3. Closing Stream Flows ......................41
           5.3.6. Closing the Connection .............................41
           5.3.7. Example ............................................42
      5.4. Direct Peer-to-Peer Streams ...............................43
           5.4.1. Connecting .........................................43
           5.4.2. Return Flows for Stream ............................43
           5.4.3. Closing the Connection .............................44
   6. IANA Considerations ............................................44
      6.1. RTMFP URI Scheme Registration .............................44
   7. Security Considerations ........................................46
   8. References .....................................................47
      8.1. Normative References ......................................47
      8.2. Informative References ....................................49
   Acknowledgements ..................................................49
   Author's Address ..................................................49
        
           4.6.5. Session Nonces .....................................26
           4.6.6. Session Sequence Number ............................26
      4.7. Packet Encryption .........................................27
           4.7.1. Cipher .............................................27
           4.7.2. Format .............................................27
           4.7.3. Verification .......................................29
                  4.7.3.1. Simple Checksum ...........................30
                  4.7.3.2. HMAC ......................................30
                  4.7.3.3. Session Sequence Number ...................31
   5. Flash Communication ............................................31
      5.1. RTMP Messages .............................................31
           5.1.1. Flow Metadata ......................................32
           5.1.2. Message Mapping ....................................34
      5.2. Flow Synchronization ......................................35
      5.3. Client-to-Server Connection ...............................36
           5.3.1. Connecting .........................................36
           5.3.2. Server-to-Client Return Control Flow ...............37
           5.3.3. setPeerInfo Command ................................37
           5.3.4. Set Keepalive Timers Command .......................39
           5.3.5. Additional Flows for Streams .......................40
                  5.3.5.1. To Server .................................40
                  5.3.5.2. From Server ...............................40
                  5.3.5.3. Closing Stream Flows ......................41
           5.3.6. Closing the Connection .............................41
           5.3.7. Example ............................................42
      5.4. Direct Peer-to-Peer Streams ...............................43
           5.4.1. Connecting .........................................43
           5.4.2. Return Flows for Stream ............................43
           5.4.3. Closing the Connection .............................44
   6. IANA Considerations ............................................44
      6.1. RTMFP URI Scheme Registration .............................44
   7. Security Considerations ........................................46
   8. References .....................................................47
      8.1. Normative References ......................................47
      8.2. Informative References ....................................49
   Acknowledgements ..................................................49
   Author's Address ..................................................49
        
1. Introduction
1. 介绍

Adobe's Secure Real-Time Media Flow Protocol (RTMFP) [RFC7016] is a general-purpose transport service for real-time media and bulk data in IP networks, and it is suited to client-server and peer-to-peer (P2P) communication. RTMFP provides a generalized framework for securing its communications according to the needs of its application.

Adobe的安全实时媒体流协议(RTMFP)[RFC7016]是IP网络中实时媒体和海量数据的通用传输服务,适用于客户端-服务器和对等(P2P)通信。RTMFP提供了一个通用框架,用于根据应用程序的需要保护其通信。

The Flash platform comprises the Flash runtime (including Flash Player) from Adobe Systems Incorporated, communication servers such as Adobe Media Server, and interoperable clients and servers provided by other parties.

Flash平台包括Adobe Systems Incorporated提供的Flash运行时(包括Flash Player)、Adobe Media Server等通信服务器以及其他方提供的可互操作客户端和服务器。

Real-time streaming network communication for the Flash platform of video, audio, and data typically uses Adobe's Real-Time Messaging Protocol (RTMP) [RTMP] messages. RTMP messages were originally designed to be transported over RTMP Chunk Stream in TCP [RTMP]; however, other transports (such as the one described in this memo) are possible.

Flash视频、音频和数据平台的实时流媒体网络通信通常使用Adobe的实时消息协议(RTMP)[RTMP]消息。RTMP消息最初设计为在TCP[RTMP]中通过RTMP块流传输;但是,也可以进行其他传输(如本备忘录中所述的传输)。

This memo specifies the syntax and semantics for transporting RTMP messages over RTMFP, and it extends Flash communication semantics to include direct P2P communication. This memo further specifies a concrete Cryptography Profile for RTMFP tailored to the application and cryptographic needs of Flash platform client-server and P2P communications.

此备忘录指定了通过RTMFP传输RTMP消息的语法和语义,并扩展了Flash通信语义,以包括直接P2P通信。本备忘录进一步规定了RTMFP的具体加密配置文件,该文件针对Flash平台客户机服务器和P2P通信的应用和加密需求而定制。

These protocols and profiles were developed by Adobe Systems Incorporated and are not the product of an IETF activity.

这些协议和配置文件由Adobe Systems Incorporated开发,不是IETF活动的产品。

2. Terminology
2. 术语

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

本文件中的关键词“必须”、“不得”、“必需”、“应”、“不应”、“建议”、“不建议”、“可”和“可选”应按照[RFC2119]中的说明进行解释。

"HMAC" means the Keyed-Hash Message Authentication Code (HMAC) algorithm [RFC2104].

“HMAC”是指密钥哈希消息认证码(HMAC)算法[RFC2104]。

"HMAC-SHA256" means HMAC using the SHA-256 Secure Hash Algorithm [SHA256] [RFC6234].

“HMAC-SHA256”指使用SHA-256安全哈希算法[SHA256][RFC6234]的HMAC。

"HMAC-SHA256(K, M)" means the calculation of the HMAC-SHA256 of message M using key K.

“HMAC-SHA256(K,M)”指使用密钥K计算消息M的HMAC-SHA256。

3. Common Syntax Elements
3. 公共语法元素

Definitions of types and structures in this specification use traditional text diagrams paired with procedural descriptions using a C-like syntax. The C-like procedural descriptions SHALL be construed as definitive.

本规范中的类型和结构定义使用传统的文本图,并使用类似C的语法进行过程描述。C类程序说明应解释为最终说明。

Structures are packed to take only as many bytes as explicitly indicated. There is no 32-bit alignment constraint, and fields are not padded for alignment unless explicitly indicated or described. Text diagrams may include a bit ruler across the top; this is a convenience for counting bits in individual fields and does not necessarily imply field alignment on a multiple of the ruler width.

结构被压缩为只占用显式指示的字节数。不存在32位对齐约束,除非明确指示或说明,否则不会填充字段进行对齐。文本图可能包括顶部的位尺;这便于计算单个字段中的位,并不一定意味着字段对齐为标尺宽度的倍数。

Unless specified otherwise, reserved fields SHOULD be set to 0 by a sender and MUST be ignored by a receiver.

除非另有规定,否则发送方应将保留字段设置为0,接收方必须忽略该字段。

The procedural syntax of this specification defines correct and error-free encoded inputs to a parser. The procedural syntax does not describe a fully featured parser, including error detection and handling. Implementations MUST include means to identify error circumstances, including truncations causing elementary or composed types not to fit inside containing structures, fields, or elements. Unless specified otherwise, an error circumstance SHALL abort the parsing and processing of an element and its enclosing elements.

本规范的过程语法定义了到解析器的正确且无错误的编码输入。过程语法没有描述功能齐全的解析器,包括错误检测和处理。实现必须包括识别错误情况的方法,包括导致基本类型或组合类型不适合包含结构、字段或元素的截断。除非另有规定,否则错误情况应中止元素及其封闭元素的解析和处理。

This memo uses the elementary and composed types described in Section 2.1 of RFC 7016. The definitions of that section are incorporated by reference as though fully set forth here.

本备忘录使用RFC 7016第2.1节所述的基本类型和组合类型。该节的定义通过引用并入,如同在此完全阐述一样。

4. Cryptography Profile
4. 密码配置文件

RTMFP defines a general security framework but delegates specifics, such as packet encryption ciphers and key agreement algorithms, to an application-defined Cryptography Profile.

RTMFP定义了一个通用的安全框架,但将一些细节(如包加密密码和密钥协商算法)委托给应用程序定义的加密配置文件。

This section defines the RTMFP Cryptography Profile for Flash platform communication.

本节定义了用于Flash平台通信的RTMFP加密配置文件。

4.1. Default Session Key
4.1. 默认会话密钥

RTMFP uses a Default Session Key and associated default cipher configuration during session startup handshaking, where session-specific keys and ciphers are negotiated.

RTMFP在会话启动握手期间使用默认会话密钥和相关的默认密码配置,会话特定的密钥和密码是协商的。

The default cipher is the Advanced Encryption Standard [AES] with 128-bit keys operating in Cipher Block Chaining [CBC] mode, as described in Section 4.7.1. The Default Session Key is the 16 bytes of the string "Adobe Systems 02" encoded in UTF-8 [RFC3629]:

默认密码为高级加密标准[AES],128位密钥以密码块链接[CBC]模式运行,如第4.7.1节所述。默认会话密钥是UTF-8[RFC3629]中编码的字符串“Adobe Systems 02”的16个字节:

Hex: 41 64 6F 62 65 20 53 79 73 74 65 6D 73 20 30 32

十六进制:41 64 6F 62 65 20 53 79 74 65 6D 73 20 30 32

The Default Session Key uses checksum mode for packet verification and does not use session sequence numbers (Section 4.7.3).

默认会话密钥使用校验和模式进行数据包验证,不使用会话序列号(第4.7.3节)。

4.2. Diffie-Hellman Groups
4.2. Diffie-Hellman群

Implementations conforming to this profile MUST support Diffie-Hellman [DH] modular exponentiation (MODP) group 2 (1024 bits) as defined in [RFC7296], and SHOULD support Diffie-Hellman MODP group 5 (1536 bits) and group 14 (2048 bits) as defined in [RFC3526]. Implementations MAY support additional groups.

符合此配置文件的实现必须支持[RFC7296]中定义的Diffie-Hellman[DH]模幂运算(MODP)组2(1024位),并应支持[RFC3526]中定义的Diffie-Hellman MODP组5(1536位)和组14(2048位)。实现可能支持其他组。

4.3. Certificates
4.3. 证书

This section defines the certificate format for this Cryptography Profile, and the mapping to the abstract properties and semantics for RTMFP endpoint identities.

本节定义此加密配置文件的证书格式,以及RTMFP端点标识到抽象属性和语义的映射。

4.3.1. Format
4.3.1. 总体安排

A certificate in this profile is encoded as a sequence of zero or more RTMFP Options and Markers (Section 2.1.3 of RFC 7016). The first marker (if any) in the certificate separates the canonical section of the certificate from the remainder. Some options are ignored if they occur outside of the canonical section (that is, after the first marker).

此配置文件中的证书编码为零个或多个RTMFP选项和标记的序列(RFC 7016第2.1.3节)。证书中的第一个标记(如果有)将证书的规范部分与其余部分分开。如果某些选项出现在规范部分之外(即第一个标记之后),则会忽略它们。

   +~~~/~~~/~~~+   +~~~/~~~/~~~+~~~~~+~~~/~~~/~~~+   +~~~/~~~/~~~+
   | L \ T \ V |...| L \ T \ V |  0  | L \ T \ V |...| L \ T \ V |
   +~~~/~~~/~~~+   +~~~/~~~/~~~+~~~~~+~~~/~~~/~~~+   +~~~/~~~/~~~+
   ^                           ^  ^  ^                           ^
   |  Zero or more non-empty   |  |  |   Zero or more Options    |
   |         Options           |  |  +------  or Markers  -------+
   |                           |  |
   +---  Canonical Section  ---+  +---- First Marker
                                        (if present)
        
   +~~~/~~~/~~~+   +~~~/~~~/~~~+~~~~~+~~~/~~~/~~~+   +~~~/~~~/~~~+
   | L \ T \ V |...| L \ T \ V |  0  | L \ T \ V |...| L \ T \ V |
   +~~~/~~~/~~~+   +~~~/~~~/~~~+~~~~~+~~~/~~~/~~~+   +~~~/~~~/~~~+
   ^                           ^  ^  ^                           ^
   |  Zero or more non-empty   |  |  |   Zero or more Options    |
   |         Options           |  |  +------  or Markers  -------+
   |                           |  |
   +---  Canonical Section  ---+  +---- First Marker
                                        (if present)
        
   struct certificate_t
   {
       canonicalStart = remainder();
       canonicalEnd = remainder();
       markerFound = false;
        
   struct certificate_t
   {
       canonicalStart = remainder();
       canonicalEnd = remainder();
       markerFound = false;
        
       while(remainder() > 0)
       {
           option_t option :variable*8;
        
       while(remainder() > 0)
       {
           option_t option :variable*8;
        
           if(0 == option.length)
               markerFound = true;
           else if(!markerFound)
               canonicalEnd = remainder();
       };
        
           if(0 == option.length)
               markerFound = true;
           else if(!markerFound)
               canonicalEnd = remainder();
       };
        
       canonicalSectionLength = canonicalStart - canonicalEnd;
   } :variable*8;
        
       canonicalSectionLength = canonicalStart - canonicalEnd;
   } :variable*8;
        
4.3.2. Fingerprint
4.3.2. 指纹

A certificate's fingerprint is the SHA-256 hash [SHA256] of the canonical section of the certificate (that is, the hash of the first canonicalSectionLength bytes of the certificate).

证书的指纹是证书规范部分的SHA-256散列[SHA256](即证书的第一个规范部分长度字节的散列)。

The certificate's fingerprint is also called the "peer ID".

证书的指纹也称为“对等ID”。

4.3.3. Options
4.3.3. 选择权

This section lists options that can appear in a certificate. The following option type codes are defined:

本节列出了可出现在证书中的选项。定义了以下选项类型代码:

0x00: Hostname (must be in canonical section) (Section 4.3.3.1)

0x00:主机名(必须在规范部分)(第4.3.3.1节)

0x0a: Accepts Ancillary Data (must be in canonical section) (Section 4.3.3.2)

0x0a:接受辅助数据(必须在规范部分)(第4.3.3.2节)

0x0e: Extra Randomness (Section 4.3.3.3)

0x0e:额外随机性(第4.3.3.3节)

0x15: Supported Ephemeral Diffie-Hellman Group (must be in canonical section) (Section 4.3.3.4)

0x15:支持的短暂Diffie-Hellman组(必须在规范部分)(第4.3.3.4节)

0x1d: Static Diffie-Hellman Public Key (must be in canonical section) (Section 4.3.3.5)

0x1d:静态Diffie-Hellman公钥(必须在规范部分)(第4.3.3.5节)

An implementation MUST ignore a certificate option type that is not understood.

实现必须忽略无法理解的证书选项类型。

4.3.3.1. Hostname
4.3.3.1. 主机名

This option gives an optional hostname for the endpoint. This option MUST be ignored if is not in the canonical section. This option MUST NOT occur more than once in a certificate.

此选项提供端点的可选主机名。如果不在规范节中,则必须忽略此选项。此选项在证书中不得出现多次。

   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x00    \ |         hostname              |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x00    \ |         hostname              |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   struct hostnameCertOptionValue_t
   {
       uint8_t hostname[remainder()];
   } :remainder()*8;
        
   struct hostnameCertOptionValue_t
   {
       uint8_t hostname[remainder()];
   } :remainder()*8;
        
4.3.3.2. Accepts Ancillary Data
4.3.3.2. 接受辅助数据

This option indicates that the endpoint will accept an Endpoint Discriminator encoding an Ancillary Data option (Section 4.4.2.2). This option MUST be ignored if it is not in the canonical section.

此选项表示端点将接受对辅助数据选项进行编码的端点鉴别器(第4.4.2.2节)。如果此选项不在规范部分中,则必须忽略它。

   +-------------/-+-------------/-+
   |   length    \ |     0x0a    \ |
   +-------------/-+-------------/-+
        
   +-------------/-+-------------/-+
   |   length    \ |     0x0a    \ |
   +-------------/-+-------------/-+
        
4.3.3.3. Extra Randomness
4.3.3.3. 额外随机性

This option can be used to add extra entropy or randomness to a certificate that doesn't have any other cryptographic pseudorandom members (such as a public key). This option is typically used so that endpoints using ephemeral Diffie-Hellman keying can have a unique certificate fingerprint.

此选项可用于向没有任何其他加密伪随机成员(如公钥)的证书添加额外的熵或随机性。此选项通常用于使使用短暂Diffie-Hellman密钥的端点可以具有唯一的证书指纹。

   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x0e    \ |       extra randomness        |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x0e    \ |       extra randomness        |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   struct extraRandomnessCertOptionValue_t
   {
       uint_t extraRandomness[remainder()];
   } :remainder()*8;
        
   struct extraRandomnessCertOptionValue_t
   {
       uint_t extraRandomness[remainder()];
   } :remainder()*8;
        
4.3.3.4. Supported Ephemeral Diffie-Hellman Group
4.3.3.4. 支持的短暂Diffie-Hellman群

This option specifies a Diffie-Hellman group ID that is supported for ephemeral keying. This option MUST be ignored if it is not in the canonical section. This option may occur more than once in the certificate; each instance indicates an additional group that is supported for key agreement.

此选项指定临时键控支持的Diffie-Hellman组ID。如果此选项不在规范部分中,则必须忽略它。此选项可能在证书中出现多次;每个实例表示密钥协议支持的其他组。

   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x15    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+
        
   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x15    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+
        
   struct ephemeralDHGroupCertOptionValue_t
   {
       vlu_t groupID :variable*8;
   } :variable*8;
        
   struct ephemeralDHGroupCertOptionValue_t
   {
       vlu_t groupID :variable*8;
   } :variable*8;
        

The presence of this option means that the certificate uses ephemeral Diffie-Hellman public keys only. The certificate MUST NOT contain a Static Diffie-Hellman public key (Section 4.3.3.5).

此选项的存在意味着证书仅使用临时Diffie-Hellman公钥。证书不得包含静态Diffie-Hellman公钥(第4.3.3.5节)。

4.3.3.5. Static Diffie-Hellman Public Key
4.3.3.5. 静态Diffie-Hellman公钥

This option specifies a Diffie-Hellman group ID and static public key in that group. This option MUST be ignored if it is not in the canonical section. This option MAY occur more than once in the certificate; however, this option SHOULD NOT occur more than once for each group ID. The behavior for specifying more than one public key per group ID is not defined.

此选项指定Diffie-Hellman组ID和该组中的静态公钥。如果此选项不在规范部分中,则必须忽略它。此选项可能在证书中出现多次;但是,对于每个组ID,此选项不应出现多次。未定义为每个组ID指定多个公钥的行为。

   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x1d    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+
   +------------------------------------------------------------------+
   |                  Diffie-Hellman Public Key                       |
   +------------------------------------------------------------------/
        
   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x1d    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+
   +------------------------------------------------------------------+
   |                  Diffie-Hellman Public Key                       |
   +------------------------------------------------------------------/
        
   struct staticDHPublicKeyCertOptionValue_t
   {
       vlu_t   groupID :variable*8;
       uintn_t publicKey :remainder()*8; // network byte order
   } :remainder()*8;
        
   struct staticDHPublicKeyCertOptionValue_t
   {
       vlu_t   groupID :variable*8;
       uintn_t publicKey :remainder()*8; // network byte order
   } :remainder()*8;
        

The presence of this option means that the certificate uses static Diffie-Hellman public keys only. The certificate MUST NOT contain any Supported Ephemeral Diffie-Hellman Group options (Section 4.3.3.4).

此选项的存在意味着证书仅使用静态Diffie-Hellman公钥。证书不得包含任何受支持的临时Diffie-Hellman组选项(第4.3.3.4节)。

4.3.4. Authenticity
4.3.4. 真实性

This profile does not use a public key infrastructure, nor are there signing keys present in certificates. Therefore, any properly encoded certificate is considered authentic according to Section 3.2 of RFC 7016.

此配置文件不使用公钥基础结构,证书中也不存在签名密钥。因此,根据RFC 7016第3.2节,任何正确编码的证书都被视为是真实的。

A certificate containing a static public key can only be used successfully for session communication if the holder of the certificate actually holds the private key associated with the public key. Authenticity of an identity and its peer ID (Section 4.3.2) having a certificate containing a static public key is implied by successful encrypted communication with the associated endpoint (Section 4.6).

只有当证书持有人实际持有与公钥关联的私钥时,包含静态公钥的证书才能成功用于会话通信。与相关端点成功加密通信(第4.6节)意味着具有包含静态公钥的证书的身份及其对等ID(第4.3.2节)的真实性。

See Section 7 for further discussion of security issues related to identities.

有关身份相关安全问题的进一步讨论,请参见第7节。

4.3.5. Signing and Verifying Messages
4.3.5. 签名和验证消息

RTMFP Initiator Initial Keying and Responder Initial Keying messages have a field for the sender's digital signature of the keying parameters (Sections 2.3.7 and 2.3.8 of RFC 7016). In this profile, the signature field of those messages is encoded as a sequence of zero or more RTMFP Options.

RTMFP发起方初始密钥设置和响应方初始密钥设置消息具有用于发送方密钥设置参数数字签名的字段(RFC 7016第2.3.7节和第2.3.8节)。在此配置文件中,这些消息的签名字段被编码为零个或多个RTMFP选项的序列。

   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   | L \ T \   V   |...............| L \ T \   V   |
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   ^                                               ^
   +-------------  Zero or more Options  ----------+
        
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   | L \ T \   V   |...............| L \ T \   V   |
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   ^                                               ^
   +-------------  Zero or more Options  ----------+
        
   struct initialKeyingSignature_t
   {
       while(remainder() > 0)
           option_t option :variable*8;
   } :remainder()*8;
        
   struct initialKeyingSignature_t
   {
       while(remainder() > 0)
           option_t option :variable*8;
   } :remainder()*8;
        

If a signer has no signature options to send, it MAY encode a signature as a UTF-8 capital "X" (hex 58) or as empty. A verifier MUST interpret a malformed signature field or a signature field consisting only of a UTF-8 capital "X" as though it was empty.

如果签名者没有要发送的签名选项,则可以将签名编码为UTF-8大写字母“X”(十六进制58)或空。验证者必须将格式错误的签名字段或仅由UTF-8大写字母“X”组成的签名字段解释为空。

If a verifier does not require a signature, it SHALL consider any signature field (including an empty or malformed one) to be valid. A verifier MAY require a signature comprising one or more non-empty options that are valid according to their respective types.

如果验证者不需要签名,则应考虑任何签名字段(包括空的或畸形的)。验证器可能需要一个签名,该签名包含一个或多个根据其各自类型有效的非空选项。

This profile does not use a public key infrastructure, nor are there signing keys present in certificates. Section 4.3.5.1.1 defines a simple ID/password credential system.

此配置文件不使用公钥基础结构,证书中也不存在签名密钥。第4.3.5.1.1节定义了一个简单的ID/密码凭证系统。

4.3.5.1. Options
4.3.5.1. 选择权

This section lists options that can appear in an RTMFP Initial Keying signature field. The following option type code is defined:

本节列出了RTMFP初始键控签名字段中可能出现的选项。定义了以下选项类型代码:

0x1d: Simple Password (Section 4.3.5.1.1)

0x1d:简单密码(第4.3.5.1.1节)

Future or derived profiles may define additional signature field options and semantics; therefore, a verifier SHOULD ignore option types that are not understood.

未来的或派生的配置文件可能会定义附加的签名字段选项和语义;因此,验证器应该忽略不理解的选项类型。

4.3.5.1.1. Simple Password
4.3.5.1.1. 简单密码

This option encodes a password identifier (such as a user name, or an application-specific or implementation-specific selector) and an HMAC over the signed parameters using the identified password as the HMAC key. This option can occur more than once (for example, to allow interoperation between a current and a previous version of an implementation using implementation-specific passwords).

此选项使用已标识的密码作为HMAC密钥,在签名参数上对密码标识符(例如用户名、特定于应用程序或特定于实现的选择器)和HMAC进行编码。此选项可以出现多次(例如,允许使用特定于实现的密码在当前版本和以前版本的实现之间进行互操作)。

To support the versioning use case, a verifier SHOULD ignore a Simple Password option encoding an unrecognized password identifier. A verifier SHOULD treat the entire signature as invalid if any Simple Password option encodes a recognized password identifier with an invalid password HMAC.

为了支持版本控制用例,验证器应该忽略编码无法识别的密码标识符的简单密码选项。如果任何简单密码选项使用无效密码HMAC对已识别的密码标识符进行编码,则验证器应将整个签名视为无效。

    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-------------/-+-------------/-+
   |   length    \ |     0x1d    \ |
   +-------------/-+-------------/-+
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                           hmacSHA256                          |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                           passwordID                          |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-------------/-+-------------/-+
   |   length    \ |     0x1d    \ |
   +-------------/-+-------------/-+
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                           hmacSHA256                          |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                           passwordID                          |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   struct simplePasswordSignatureOptionValue_t
   {
       uint8_t hmacSHA256[32];
       uint8_t passwordID[remainder()];
   } :remainder()*8;
        
   struct simplePasswordSignatureOptionValue_t
   {
       uint8_t hmacSHA256[32];
       uint8_t passwordID[remainder()];
   } :remainder()*8;
        

hmacSHA256: HMAC-SHA256(K, M), where K is the password associated with passwordID, and M is the signed parameters.

hmacSHA256:HMAC-SHA256(K,M),其中K是与passwordID关联的密码,M是签名参数。

passwordID: The identifier (such as a user name) for the password used as the HMAC key.

passwordID:用作HMAC密钥的密码的标识符(如用户名)。

4.3.6. Glare Resolution
4.3.6. 眩光分辨率

Glare occurs when two endpoints initiate a session each to the other concurrently.

当两个端点同时向另一个端点发起会话时,会发生眩光。

Compare the near end's certificate to the far end's with a binary lexicographic comparison, one byte at a time, up to the length of the shorter certificate. At the first corresponding byte from each certificate that is different, the certificate having the differing byte (treated as an unsigned 8-bit integer) with the lower value is ordered before the other certificate. If the certificates are not the same length and they are identical up to the length of the shorter certificate, then the shorter certificate is ordered before the longer.

使用二进制字典比较法比较近端证书和远端证书,每次比较一个字节,直到较短证书的长度。在每个不同证书的第一个对应字节处,具有较低值的不同字节(视为无符号8位整数)的证书在另一个证书之前排序。如果证书的长度不相同,并且在较短证书的长度内它们是相同的,则较短的证书在较长的证书之前排序。

The near end prevails as the Initiator in case of glare if its certificate is ordered before, or is identical to, the certificate of the far end. Otherwise, the near end's certificate is ordered after the far end's certificate, and the near end assumes the role of Responder.

如果近端证书是在远端证书之前订购的,或与远端证书相同,则在眩光情况下,近端作为启动器优先。否则,近端的证书将在远端的证书之后排序,近端将承担响应者的角色。

4.3.7. Session Override
4.3.7. 会话覆盖

A new incoming session overrides an existing session only if the certificate for the new session is identical to the certificate for the existing session.

仅当新会话的证书与现有会话的证书相同时,新传入会话才会覆盖现有会话。

4.4. Endpoint Discriminators
4.4. 端点鉴别器

This section describes the Endpoint Discriminator (EPD) (Section 3.2 of RFC 7016) format and semantics for this Cryptography Profile, and the mapping to RTMFP's abstract certificate and identity selection semantics.

本节描述了此加密配置文件的端点鉴别器(EPD)(RFC 7016第3.2节)格式和语义,以及到RTMFP的抽象证书和身份选择语义的映射。

4.4.1. Format
4.4.1. 总体安排

An EPD in this profile is encoded as a sequence of zero or more RTMFP Options.

此配置文件中的EPD编码为零个或多个RTMFP选项序列。

   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   | L \ T \   V   |...............| L \ T \   V   |
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   ^                                               ^
   +-------------  Zero or more Options  ----------+
        
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   | L \ T \   V   |...............| L \ T \   V   |
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   ^                                               ^
   +-------------  Zero or more Options  ----------+
        
   struct endpointDiscriminator_t
   {
       while(remainder() > 0)
           option_t option :variable*8;
   } :remainder()*8;
        
   struct endpointDiscriminator_t
   {
       while(remainder() > 0)
           option_t option :variable*8;
   } :remainder()*8;
        
4.4.2. Options
4.4.2. 选择权

This section lists options that can appear in an EPD. The following option type codes are defined:

本节列出了可出现在EPD中的选项。定义了以下选项类型代码:

0x00: Required Hostname (Section 4.4.2.1)

0x00:所需主机名(第4.4.2.1节)

0x0a: Ancillary Data (Section 4.4.2.2)

0x0a:辅助数据(第4.4.2.2节)

0x0f: Fingerprint (Section 4.4.2.3)

0x0f:指纹(第4.4.2.3节)

The use of these options for selecting certificates is described in Section 4.4.3.

第4.4.3节介绍了使用这些选项选择证书。

An implementation MUST ignore EPD option types that are not understood.

实现必须忽略未理解的EPD选项类型。

4.4.2.1. Required Hostname
4.4.2.1. 所需主机名

This option indicates the hostname to match against the certificate's Hostname option (Section 4.3.3.1).

此选项指示要与证书的主机名选项匹配的主机名(第4.3.3.1节)。

   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x00    \ |         hostname              |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x00    \ |         hostname              |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   struct hostnameEPDOptionValue_t
   {
       uint8_t hostname[remainder()];
   } :remainder()*8;
        
   struct hostnameEPDOptionValue_t
   {
       uint8_t hostname[remainder()];
   } :remainder()*8;
        

This option MUST NOT occur more than once in an EPD.

此选项在EPD中不得出现多次。

4.4.2.2. Ancillary Data
4.4.2.2. 辅助资料

In this profile, this option indicates the server Uniform Resource Identifier (URI) [RFC3986] encoded in UTF-8 to which a client is connecting on this session, for example, "rtmfp://server.example.com/app/instance".

在此配置文件中,此选项表示以UTF-8编码的服务器统一资源标识符(URI)[RFC3986],例如,客户端在此会话上连接到该服务器rtmfp://server.example.com/app/instance".

   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x0a    \ |       ancillary data          |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x0a    \ |       ancillary data          |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   struct ancillaryDataEPDOptionValue_t
   {
       uint8_t ancillaryData[remainder()];
   } :remainder()*8;
        
   struct ancillaryDataEPDOptionValue_t
   {
       uint8_t ancillaryData[remainder()];
   } :remainder()*8;
        

This option MUST NOT occur more than once in an EPD.

此选项在EPD中不得出现多次。

4.4.2.3. Fingerprint
4.4.2.3. 指纹

This option indicates the 256-bit (32-byte) fingerprint (Section 4.3.2) of a certificate.

此选项表示证书的256位(32字节)指纹(第4.3.2节)。

    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-------------/-+-------------/-+
   |   length    \ |     0x0f    \ |
   +-------------/-+-------------/-+
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                          fingerprint                          |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        
    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-------------/-+-------------/-+
   |   length    \ |     0x0f    \ |
   +-------------/-+-------------/-+
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                          fingerprint                          |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        
   struct fingerprintEPDOptionValue_t
   {
       uint8_t fingerprint[32];
   } :256;
        
   struct fingerprintEPDOptionValue_t
   {
       uint8_t fingerprint[32];
   } :256;
        

This option MUST NOT occur more than once in an EPD.

此选项在EPD中不得出现多次。

4.4.3. Certificate Selection
4.4.3. 证书选择

This section describes the REQUIRED method of determining whether an EPD selects a certificate.

本节介绍了确定环保署是否选择证书所需的方法。

An EPD MUST contain at least one of Fingerprint, Required Hostname, or Ancillary Data options to select any certificate.

EPD必须至少包含一个指纹、所需主机名或辅助数据选项,才能选择任何证书。

A Fingerprint EPD option selects or rejects a certificate no matter what other options are present.

指纹EPD选项选择或拒绝证书,无论存在其他选项。

Without a Fingerprint option, a Required Hostname EPD option, if present, REQUIRES an identical Hostname option in the certificate.

如果没有指纹选项,则所需的主机名EPD选项(如果存在)需要证书中的相同主机名选项。

Without a Fingerprint option, an Ancillary Data EPD option, if present, REQUIRES that the certificate has an Accepts Ancillary Data option.

如果没有指纹选项,辅助数据EPD选项(如果存在)要求证书具有“接受辅助数据”选项。

if EPD contains a Fingerprint option: if certificate.fingerprint == option.fingerprint: certificate is selected. stop. else: certificate is not selected. stop. else: if EPD contains a Required Hostname option: if certificate contains a Hostname option: if certificate.hostname != option.hostname: certificate is not selected. stop. else: certificate is not selected. stop. if EPD contains an Ancillary Data option: if certificate doesn't have an Accepts Ancillary Data option: certificate is not selected. stop. else if EPD does not contain a Required Hostname option: certificate is not selected. stop. certificate is selected. stop.

如果EPD包含指纹选项:如果选择了certificate.Fingerprint==选项。指纹:证书。停止否则:未选择证书。停止else:如果EPD包含所需的主机名选项:如果证书包含主机名选项:如果certificate.Hostname!=option.hostname:未选择证书。停止否则:未选择证书。停止如果EPD包含辅助数据选项:如果证书没有接受辅助数据选项:未选择证书。停止否则,如果EPD不包含所需的主机名选项:未选择证书。停止已选择证书。停止

Figure 1: Algorithm to Test Whether an EPD Selects a Certificate

图1:测试EPD是否选择证书的算法

4.4.4. Canonical Endpoint Discriminator
4.4.4. 标准端点鉴别器

In this profile, a Canonical Endpoint Discriminator (Section 3.2 of RFC 7016) contains only a Fingerprint option (Section 4.4.2.3) and no other options. The option length and type code MUST be encoded as 1-byte VLUs, even though VLU encoding allows those fields to be encoded in an arbitrary number of bytes. That is, the Canonical Endpoint Discriminator MUST be exactly 34 bytes long, with a length field of 0x21 encoded as one byte, a type code of 0x0f encoded as one byte, and 32 bytes of fingerprint.

在此配置文件中,标准端点鉴别器(RFC 7016第3.2节)仅包含指纹选项(第4.4.2.3节),不包含其他选项。选项长度和类型代码必须编码为1字节VLU,即使VLU编码允许这些字段以任意字节数编码。也就是说,规范端点鉴别器的长度必须正好为34字节,长度字段0x21编码为一个字节,类型代码0x0f编码为一个字节,指纹长度为32字节。

    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     0x21      |     0x0f      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                          fingerprint                          |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        
    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     0x21      |     0x0f      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                          fingerprint                          |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        
   struct canonicalEndpointDiscriminator_t
   {
       uint8_t length = 0x21;
       uint8_t type = 0x0f;
       uint8_t fingerprint[32];
   } :272;
        
   struct canonicalEndpointDiscriminator_t
   {
       uint8_t length = 0x21;
       uint8_t type = 0x0f;
       uint8_t fingerprint[32];
   } :272;
        
4.5. Session Keying Components
4.5. 会话键控组件

This section describes the format of the Session Key Initiator Component of the Initiator Initial Keying RTMFP chunk and the Session Key Responder Component of the Responder Initial Keying RTMFP chunk (Sections 2.3.7 and 2.3.8 of RFC 7016). The Initiator and Responder Session Keying Components have the same format.

本节描述了启动器初始键控RTMFP区块的会话密钥启动器组件和响应器初始键控RTMFP区块的会话密钥响应器组件的格式(RFC 7016第2.3.7节和第2.3.8节)。启动器和响应程序会话键控组件具有相同的格式。

4.5.1. Format
4.5.1. 总体安排

A Session Keying Component in this profile is encoded as a sequence of zero or more RTMFP Options.

此配置文件中的会话键控组件编码为零个或多个RTMFP选项序列。

   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   | L \ T \   V   |...............| L \ T \   V   |
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   ^                                               ^
   +-------------  Zero or more Options  ----------+
        
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   | L \ T \   V   |...............| L \ T \   V   |
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   ^                                               ^
   +-------------  Zero or more Options  ----------+
        
   struct sessionKeyingComponent_t
   {
       while(remainder() > 0)
           option_t option :variable*8;
   } :remainder()*8;
        
   struct sessionKeyingComponent_t
   {
       while(remainder() > 0)
           option_t option :variable*8;
   } :remainder()*8;
        
4.5.2. Options
4.5.2. 选择权

This section lists options that can appear in a Session Keying Component. The following option type codes are defined:

本节列出了可出现在会话键控组件中的选项。定义了以下选项类型代码:

0x0d: Ephemeral Diffie-Hellman Public Key (Section 4.5.2.1)

0x0d:临时Diffie-Hellman公钥(第4.5.2.1节)

0x0e: Extra Randomness (Section 4.5.2.2)

0x0e:额外随机性(第4.5.2.2节)

0x1d: Diffie-Hellman Group Select (Section 4.5.2.3)

0x1d:Diffie-Hellman组选择(第4.5.2.3节)

0x1a: HMAC Negotiation (Section 4.5.2.4)

0x1a:HMAC协商(第4.5.2.4节)

0x1e: Session Sequence Number Negotiation (Section 4.5.2.5)

0x1e:会话序列号协商(第4.5.2.5节)

An implementation MUST ignore a session keying component option type that is not understood.

实现必须忽略未理解的会话键控组件选项类型。

4.5.2.1. Ephemeral Diffie-Hellman Public Key
4.5.2.1. 短暂Diffie-Hellman公钥

This option specifies a Diffie-Hellman group ID and public key in that group. This option MUST NOT be sent if the sender's certificate has a static Diffie-Hellman public key. This option MUST be sent if the sender's certificate does not have a static Diffie-Hellman public key. This option MUST NOT be sent more than once.

此选项指定该组中的Diffie-Hellman组ID和公钥。如果发件人的证书具有静态Diffie-Hellman公钥,则不得发送此选项。如果发件人的证书没有静态Diffie-Hellman公钥,则必须发送此选项。此选项只能发送一次。

   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x0d    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+
   +------------------------------------------------------------------+
   |                  Diffie-Hellman Public Key                       |
   +------------------------------------------------------------------/
        
   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x0d    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+
   +------------------------------------------------------------------+
   |                  Diffie-Hellman Public Key                       |
   +------------------------------------------------------------------/
        
   struct ephemeralDHPublicKeyKeyingOptionValue_t
   {
       vlu_t   groupID :variable*8;
       uintn_t publicKey :remainder()*8; // network byte order
   } :remainder()*8;
        
   struct ephemeralDHPublicKeyKeyingOptionValue_t
   {
       vlu_t   groupID :variable*8;
       uintn_t publicKey :remainder()*8; // network byte order
   } :remainder()*8;
        
4.5.2.2. Extra Randomness
4.5.2.2. 额外随机性

This option can be used to add extra entropy or randomness to a keying component, particularly when the sender uses a static public key. When used for that purpose, the extra randomness SHOULD be cryptographically strong pseudorandom bytes not less than 16 bytes (for cryptographically significant entropy) and not more than 64 bytes (the length of a SHA-256 input block) in length. The extra randomness serves as a salt when computing the session keys (Section 4.6).

此选项可用于向键控组件添加额外的熵或随机性,尤其是当发送方使用静态公钥时。当用于该目的时,额外的随机性应为加密强伪随机字节,长度不小于16字节(对于加密有效熵),不大于64字节(SHA-256输入块的长度)。在计算会话密钥时,额外的随机性可作为一种盐(第4.6节)。

   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x0e    \ |       extra randomness        |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x0e    \ |       extra randomness        |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   struct extraRandomnessKeyingOptionValue_t
   {
       uint_t extraRandomness[remainder()];
   } :remainder()*8;
        
   struct extraRandomnessKeyingOptionValue_t
   {
       uint_t extraRandomness[remainder()];
   } :remainder()*8;
        
4.5.2.3. Diffie-Hellman Group Select
4.5.2.3. Diffie-Hellman组选择

This option is sent by the Initiator to specify which Diffie-Hellman group to use for key agreement. The Initiator MUST send this option when it advertises a static Diffie-Hellman public key in its certificate and MUST NOT send this option if it sends an ephemeral Diffie-Hellman public key. This option MUST NOT be sent more than once.

此选项由发起方发送,以指定用于密钥协商的Diffie Hellman组。发起方在其证书中播发静态Diffie-Hellman公钥时必须发送此选项,如果发送临时Diffie-Hellman公钥,则不得发送此选项。此选项只能发送一次。

   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x1d    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+
        
   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x1d    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+
        
   struct staticDHGroupSelectKeyingOptionValue_t
   {
       vlu_t   groupID :variable*8;
   } :variable*8;
        
   struct staticDHGroupSelectKeyingOptionValue_t
   {
       vlu_t   groupID :variable*8;
   } :variable*8;
        
4.5.2.4. HMAC Negotiation
4.5.2.4. HMAC谈判

This option is used to negotiate sending and receiving of an HMAC field for packet verification.

此选项用于协商发送和接收HMAC字段以进行数据包验证。

                                   |0 1 2 3 4 5 6 7|
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+-------------/-+
   |             \ |             \ |         |S|S|R|             \ |
   |   length    / |     0x1a    / |   rsv   |N|O|E|  hmacLength / |
   |             \ |             \ |         |D|R|Q|             \ |
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+-------------/-+
        
                                   |0 1 2 3 4 5 6 7|
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+-------------/-+
   |             \ |             \ |         |S|S|R|             \ |
   |   length    / |     0x1a    / |   rsv   |N|O|E|  hmacLength / |
   |             \ |             \ |         |D|R|Q|             \ |
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+-------------/-+
        
   struct hmacNegotiationKeyingOptionValue_t
   {
       uintn_t reserved :5;          // rsv
       bool_t  willSendAlways :1;    // SND
       bool_t  willSendOnRequest :1; // SOR
       bool_t  request :1;           // REQ
       vlu_t   hmacLength :variable*8;
   } :variable*8;
        
   struct hmacNegotiationKeyingOptionValue_t
   {
       uintn_t reserved :5;          // rsv
       bool_t  willSendAlways :1;    // SND
       bool_t  willSendOnRequest :1; // SOR
       bool_t  request :1;           // REQ
       vlu_t   hmacLength :variable*8;
   } :variable*8;
        

willSendAlways: If set, the sender will send an HMAC on packets in this session.

willSendAlways:如果已设置,则发送方将在此会话中发送数据包上的HMAC。

willSendOnRequest: If set, the sender will send an HMAC on packets in this session if the other end sets the request flag in its HMAC Negotiation.

willSendOnRequest:如果已设置,则如果另一端在其HMAC协商中设置了请求标志,则发送方将在此会话中对数据包发送HMAC。

request: If set, the sender would very much like the receiver to send an HMAC on its packets. If the other end doesn't send an HMAC on its packets, the session can fail.

请求:如果设置了,发送方将非常希望接收方在其数据包上发送HMAC。如果另一端不在其数据包上发送HMAC,会话可能会失败。

hmacLength: If the sender negotiates to send an HMAC on its packets, the HMAC field will be this many bytes long. This value MUST be between 4 and 32 inclusive, or 0 if and only if willSendAlways and willSendOnRequest are clear.

hmacLength:如果发送方协商在其数据包上发送HMAC,HMAC字段将有这么多字节长。当且仅当willSendAlways和willSendOnRequest清除时,此值必须介于4和32之间(含4和32),或为0。

The handshake operational semantics for this option are described in Section 4.6.4.

第4.6.4节描述了该选项的握手操作语义。

4.5.2.5. Session Sequence Number Negotiation
4.5.2.5. 会话序列号协商

This option is used to negotiate sending and receiving of the Session Sequence Number field for packet verification.

此选项用于协商会话序列号字段的发送和接收,以进行数据包验证。

                                   |0 1 2 3 4 5 6 7|
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+
   |             \ |             \ |         |S|S|R|
   |   length    / |     0x1e    / |   rsv   |N|O|E|
   |             \ |             \ |         |D|R|Q|
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+
        
                                   |0 1 2 3 4 5 6 7|
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+
   |             \ |             \ |         |S|S|R|
   |   length    / |     0x1e    / |   rsv   |N|O|E|
   |             \ |             \ |         |D|R|Q|
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+
        
   struct sseqNegotiationKeyingOptionValue_t
   {
       uintn_t reserved :5;          // rsv
       bool_t  willSendAlways :1;    // SND
       bool_t  willSendOnRequest :1; // SOR
       bool_t  request :1;           // REQ
   } :8;
        
   struct sseqNegotiationKeyingOptionValue_t
   {
       uintn_t reserved :5;          // rsv
       bool_t  willSendAlways :1;    // SND
       bool_t  willSendOnRequest :1; // SOR
       bool_t  request :1;           // REQ
   } :8;
        

willSendAlways: If set, the sender will send a session sequence number in packets in this session.

willSendAlways:如果设置,发送方将在此会话中以数据包的形式发送会话序列号。

willSendOnRequest: If set, the sender will send a session sequence number in packets in this session if the other end sets the request flag in its Session Sequence Number Negotiation.

willSendOnRequest:如果设置,则如果另一端在其会话序列号协商中设置了请求标志,则发送方将在此会话中以数据包的形式发送会话序列号。

request: If set, the sender would very much like the receiver to send a session sequence number in its packets. If the other end doesn't send a session sequence number in its packets, the session can fail.

请求:如果设置了,发送方将非常希望接收方在其数据包中发送会话序列号。如果另一端未在其数据包中发送会话序列号,则会话可能会失败。

The handshake operational semantics for this option are described in Section 4.6.6.

第4.6.6节描述了该选项的握手操作语义。

4.6. Session Key Computation
4.6. 会话密钥计算

This section describes how to compute the cryptographic keys and other settings for packet encryption and verification.

本节介绍如何计算用于数据包加密和验证的加密密钥和其他设置。

The Session Key Near Component (SKNC) means the keying component sent by the near end of the session; that is, it is the Session Key Initiator Component at the Initiator and the Session Key Responder Component at the Responder.

会话密钥近端组件(SKNC)是指会话近端发送的密钥组件;也就是说,它是发起方的会话密钥发起方组件和响应方的会话密钥响应方组件。

The Session Key Far Component (SKFC) means the keying component sent by the far end of the session; that is, it is the Session Key Responder Component at the Initiator and the Session Key Initiator Component at the Responder.

会话密钥远端组件(SKFC)指会话远端发送的密钥组件;也就是说,它是发起方的会话密钥响应方组件和响应方的会话密钥发起方组件。

4.6.1. Public Key Selection
4.6.1. 公钥选择

This section enumerates the public key selection methods for all possible combinations of static or ephemeral public key modes for each endpoint according to their certificate options (Section 4.3.3).

本节根据每个端点的证书选项(第4.3.3节),列举了所有可能的静态或临时公钥模式组合的公钥选择方法。

4.6.1.1. Initiator and Responder Ephemeral
4.6.1.1. 发起人和响应人短暂的

The Initiator and Responder list one or more Supported Ephemeral Diffie-Hellman Group options (Section 4.3.3.4) in their certificates. The Initiator sends exactly one Ephemeral Diffie-Hellman Public Key option (Section 4.5.2.1) in its Session Key Initiator Component, which selects one group from among those supported by the Responder and Initiator. Responder sends exactly one Ephemeral Diffie-Hellman Public Key option in its Session Key Responder Component, in the same group as indicated by the Initiator.

启动器和响应程序在其证书中列出一个或多个受支持的临时Diffie-Hellman组选项(第4.3.3.4节)。发起方在其会话密钥发起方组件中只发送一个临时Diffie-Hellman公钥选项(第4.5.2.1节),该选项从响应方和发起方支持的组中选择一个组。响应程序在其会话密钥响应程序组件中发送一个临时Diffie-Hellman公钥选项,该选项位于启动器指示的同一组中。

4.6.1.2. Initiator Ephemeral and Responder Static
4.6.1.2. 发起者短暂和响应者静态

The Responder lists one or more Static Diffie-Hellman Public Key options (Section 4.3.3.5) in its certificate. The Initiator lists one or more Supported Ephemeral Diffie-Hellman Group options in its certificate. The Initiator sends exactly one Ephemeral Diffie-Hellman Public Key option in its Session Key Initiator Component, which selects one group from among those supported by the Responder and Initiator and the corresponding public key for the Responder. Responder uses its public key from the indicated group, and sends only an Extra Randomness option (Section 4.5.2.2) in its Session Key Responder Component to salt the session keys.

响应者在其证书中列出一个或多个静态Diffie-Hellman公钥选项(第4.3.3.5节)。启动器在其证书中列出一个或多个受支持的临时Diffie-Hellman组选项。发起方在其会话密钥发起方组件中只发送一个临时Diffie-Hellman公钥选项,该选项从响应方和发起方支持的组中选择一个组,并为响应方发送相应的公钥。响应程序使用指定组中的公钥,并在其会话密钥响应程序组件中仅发送一个额外的随机选项(第4.5.2.2节),以添加会话密钥。

4.6.1.3. Initiator Static and Responder Ephemeral
4.6.1.3. 发起者静态和响应者短暂

The Responder lists one or more Supported Ephemeral Diffie-Hellman Group options in its certificate. The Initiator lists one or more Static Diffie-Hellman Public Key options in its certificate. The Initiator sends exactly one Diffie-Hellman Group Select option (Section 4.5.2.3) in its Session Key Initiator Component, which selects one group from among those supported by the Responder and Initiator and the corresponding public key for the Initiator, plus an Extra Randomness option to salt the session keys. The Responder sends an Ephemeral Diffie-Hellman Public Key option in its Session Key Responder Component in the same group as indicated by the Initiator.

响应程序在其证书中列出一个或多个受支持的临时Diffie-Hellman组选项。启动器在其证书中列出一个或多个静态Diffie-Hellman公钥选项。发起方在其会话密钥发起方组件中只发送一个Diffie-Hellman组选择选项(第4.5.2.3节),该选项从响应方和发起方支持的组中选择一个组,并为发起方发送相应的公钥,外加一个额外的随机选项来添加会话密钥。响应程序在发起程序指示的同一组中的会话密钥响应程序组件中发送临时Diffie-Hellman公钥选项。

4.6.1.4. Initiator and Responder Static
4.6.1.4. 启动器和响应程序静态

The Initiator and Responder each list one or more Static Diffie-Hellman Public Key options in their certificates. The Initiator sends exactly one Diffie-Hellman Group Select option in its Session Key Initiator Component, which selects one group and corresponding public keys from among those supported by the Responder and Initiator, and an Extra Randomness option to salt the session keys. The Responder sends an Extra Randomness option in its Session Key Responder Component to add its own salt to the session keys.

发起方和响应方各自在其证书中列出一个或多个静态Diffie-Hellman公钥选项。发起程序在其会话密钥发起程序组件中只发送一个Diffie-Hellman Group Select选项,该选项从响应程序和发起程序支持的组中选择一个组和相应的公钥,并发送一个额外的随机性选项来添加会话密钥。响应程序在其会话密钥响应程序组件中发送一个额外的随机性选项,以向会话密钥添加自己的salt。

4.6.2. Diffie-Hellman Shared Secret
4.6.2. 迪菲·赫尔曼分享秘密

To be acceptable, a Diffie-Hellman public key MUST have all of the following properties:

Diffie-Hellman公钥必须具有以下所有属性才能被接受:

o Be at least 16777216 (2^24);

o 至少为16777216(2^24);

o Be at most the group's prime modulus minus 16777216;

o 至多为群的素数模减16777216;

o Have at least 16 "1" bits;

o 至少有16个“1”位;

o Have at least 16 "0" bits, not including leading zeros.

o 至少有16个“0”位,不包括前导零。

An endpoint MUST NOT complete to an S_OPEN session with a far endpoint using a public key that is not acceptable according to these criteria.

端点不得使用公钥完成与远端端点的S_OPEN会话,根据这些标准,公钥是不可接受的。

Once the group and corresponding public key of the far end is determined, the far end's public key and the near end's private key are combined according to Diffie-Hellman [DH] to compute the Diffie-Hellman Shared Secret, an integer.

一旦确定了远端的组和相应的公钥,则根据Diffie-Hellman[DH]组合远端的公钥和近端的私钥,以计算Diffie-Hellman共享密钥,即整数。

In the following sections, DH_SECRET means the Diffie-Hellman Shared Secret encoded as a byte-aligned unsigned integer in network byte order with no leading zero bytes. For example, if the shared secret is 4886718345, DH_SECRET would be the five bytes:

在以下各节中,DH_SECRET是指Diffie Hellman共享密钥,编码为网络字节顺序的字节对齐无符号整数,无前导零字节。例如,如果共享密钥是4886718345,则DH_secret将是五个字节:

Hex: 01 23 45 67 89

十六进制:01 23 45 67 89

4.6.3. Packet Encrypt/Decrypt Keys
4.6.3. 数据包加密/解密密钥

Packets are encrypted using a symmetric cipher, such as the Advanced Encryption Standard [AES]. Distinct keys are used for sending and receiving packets. Each end's sending (encrypt) key is the other end's receiving (decrypt) key.

数据包使用对称密码加密,如高级加密标准[AES]。不同的密钥用于发送和接收数据包。每一端的发送(加密)密钥是另一端的接收(解密)密钥。

The raw keys computed in this section for encryption and decryption are transformed in a manner specific to the cipher with which they are to be used. In this profile, AES-128 is the only currently defined cipher. For this cipher, the first 128 bits (16 bytes) of the 256-bit output of the calculation are taken to be the AES-128 key.

本节中计算的用于加密和解密的原始密钥以特定于使用它们的密码的方式进行转换。在此配置文件中,AES-128是当前唯一定义的密码。对于该密码,计算的256位输出的前128位(16字节)被视为AES-128密钥。

      Set ENCRYPT_KEY = HMAC-SHA256(DH_SECRET, HMAC-SHA256(SKFC, SKNC));
        
      Set ENCRYPT_KEY = HMAC-SHA256(DH_SECRET, HMAC-SHA256(SKFC, SKNC));
        
      Set DECRYPT_KEY = HMAC-SHA256(DH_SECRET, HMAC-SHA256(SKNC, SKFC));
        
      Set DECRYPT_KEY = HMAC-SHA256(DH_SECRET, HMAC-SHA256(SKNC, SKFC));
        

The full 256 bits of ENCRYPT_KEY and DECRYPT_KEY are used in the computations in the following sections.

在以下部分的计算中使用完整的256位加密密钥和解密密钥。

4.6.4. Packet HMAC Send/Receive Keys
4.6.4. 分组HMAC发送/接收密钥

Packets can be verified that they were not corrupted or modified by appending an HMAC to the packet. Whether to use an HMAC or a simple checksum is determined during the initial keying phase using the HMAC Negotiation option (Section 4.5.2.4). Distinct HMAC keys are used for sending and receiving packets. Each end's sending key is the other end's receiving key, and vice versa.

通过向数据包添加HMAC,可以验证数据包是否已损坏或修改。使用HMAC协商选项(第4.5.2.4节)在初始键控阶段确定是使用HMAC还是简单校验和。不同的HMAC密钥用于发送和接收数据包。每一端的发送密钥是另一端的接收密钥,反之亦然。

      Set HMAC_SEND_KEY = HMAC_SHA256(DH_SECRET, ENCRYPT_KEY);
        
      Set HMAC_SEND_KEY = HMAC_SHA256(DH_SECRET, ENCRYPT_KEY);
        
      Set HMAC_RECV_KEY = HMAC_SHA256(DH_SECRET, DECRYPT_KEY);
        
      Set HMAC_RECV_KEY = HMAC_SHA256(DH_SECRET, DECRYPT_KEY);
        

If an endpoint sets the willSendAlways flag in its HMAC Negotiation option, then it MUST send an HMAC on packets it sends with this session key.

如果端点在其HMAC协商选项中设置了willSendAlways标志,那么它必须在使用此会话密钥发送的数据包上发送HMAC。

If an endpoint's willSendAlways flag is clear but its willSendOnRequest flag is set, then it MUST send an HMAC on packets it sends with this session key if and only if the other endpoint's request flag is set.

如果一个端点的willSendAlways标志是清除的,但其willSendOnRequest标志已设置,则只有当且仅当另一个端点的request标志已设置时,该端点才能在使用此会话密钥发送的数据包上发送HMAC。

If a sending endpoint's willSendAlways and willSendOnRequest flags are clear, then the receiving endpoint SHOULD reject that keying component if the receiving endpoint is configured to require the sending endpoint to send HMAC.

如果发送端点的willSendAlways和willSendOnRequest标志清除,则如果接收端点配置为要求发送端点发送HMAC,则接收端点应拒绝该键控组件。

If HMAC is negotiated to be used, the corresponding hmacLength MUST be between 4 and 32 inclusive.

如果协商使用HMAC,则相应的HMAC长度必须介于4和32之间(含4和32)。

If HMAC is negotiated not to be used, a simple checksum is used for packet verification.

如果协商不使用HMAC,则使用简单校验和进行数据包验证。

The Default Session Key uses the simple checksum and does not use HMAC.

默认会话密钥使用简单校验和,不使用HMAC。

4.6.5. Session Nonces
4.6.5. 会话时隙

Session nonces are per-session, cryptographically strong secret values known only to the two endpoints of the session. They can be used for application-layer cryptographic challenges (such as signing or password verification). These nonces are a convenience being pre-shared and pre-agreed-upon in a secure manner during the initial keying handshake.

会话nonce是每个会话的密码强秘密值,只有会话的两个端点知道。它们可用于应用层加密挑战(如签名或密码验证)。这些nonce是在初始键控握手期间以安全方式预先共享和预先约定的便利。

Each end's near nonce is the other end's far nonce, and vice versa.

每一端的近时点是另一端的远时点,反之亦然。

      Set NEAR_NONCE = HMAC_SHA256(DH_SECRET, SKNC);
        
      Set NEAR_NONCE = HMAC_SHA256(DH_SECRET, SKNC);
        
      Set FAR_NONCE = HMAC_SHA256(DH_SECRET, SKFC);
        
      Set FAR_NONCE = HMAC_SHA256(DH_SECRET, SKFC);
        
4.6.6. Session Sequence Number
4.6.6. 会话序列号

Duplicate packets can be detected and rejected by using an optional session sequence number inside the encrypted packets. The session sequence number is a monotonically increasing unbounded integer and does not wrap. Session sequence numbers SHOULD start at zero and SHOULD increment by one for each packet sent using that session key. Implementations MUST handle session sequence numbers with no less than 64 bits of range.

通过在加密的数据包中使用可选的会话序列号,可以检测并拒绝重复的数据包。会话序列号是一个单调递增的无界整数,不换行。会话序列号应该从零开始,并且对于使用该会话密钥发送的每个数据包,会话序列号应该递增1。实现必须处理范围不小于64位的会话序列号。

If an endpoint's willSendAlways flag in its Session Sequence Number Negotiation option (Section 4.5.2.5) is set, then it MUST send a session sequence number in packets it sends with this session key.

如果在其会话序列号协商选项(第4.5.2.5节)中设置了端点的willSendAlways标志,则它必须在使用此会话密钥发送的数据包中发送会话序列号。

If an endpoint's willSendAlways flag is clear but its willSendOnRequest flag is set, then it MUST send a session sequence number on packets it sends with this session key if and only if the other endpoint's request flag is set.

如果一个端点的willSendAlways标志是清除的,但其willSendOnRequest标志已设置,则只有当且仅当另一个端点的request标志已设置时,该端点才能在使用此会话密钥发送的数据包上发送会话序列号。

If a sending endpoint's willSendAlways and willSendOnRequest flags are clear, then the receiving endpoint SHOULD reject that keying component if the receiving endpoint is configured to require the sending endpoint to send session sequence numbers.

如果发送端点的willSendAlways和willSendOnRequest标志清除,则如果接收端点配置为要求发送端点发送会话序列号,则接收端点应拒绝该键控组件。

The Default Session Key does not use session sequence numbers.

默认会话密钥不使用会话序列号。

4.7. Packet Encryption
4.7. 包加密

This section describes the concrete syntax and operational semantics of RTMFP packet encryption for this Cryptography Profile.

本节介绍此加密配置文件的RTMFP数据包加密的具体语法和操作语义。

4.7.1. Cipher
4.7.1. 密码

This profile defines AES-128 [AES] in CBC [CBC] mode as the only cipher. Extensions to this profile can specify and negotiate additional ciphers and modes by defining certificate and keying component options and associated semantics.

此配置文件将CBC[CBC]模式下的AES-128[AES]定义为唯一的密码。此概要文件的扩展可以通过定义证书和密钥组件选项以及相关语义来指定和协商其他密码和模式。

For AES-128-CBC, the initialization vector (IV) for each packet is 16 zero bytes. The IV is not included in the packet.

对于AES-128-CBC,每个数据包的初始化向量(IV)为16个零字节。IV不包括在包装中。

4.7.2. Format
4.7.2. 总体安排

The Encrypted Packet is the encryptedPacket field of an RTMFP Multiplex packet (Section 2.2.2 of RFC 7016); that is, the portion of the Multiplex packet following the scrambled session ID. The Encrypted Packet has the following format:

加密包是RTMFP多路传输包的encryptedPacket字段(RFC 7016第2.2.2节);即,在加扰会话ID之后的复用分组的部分。加密分组具有以下格式:

   +----------------+     +----------------+~~~~~~~~~~~~~~~~~~~~~~~+
   |  CBC Block 1   | ... |  CBC Block N   |     truncatedHMAC     |
   +----------------+     +----------------+~~~~~~~~~~~~~~~~~~~~~~~+
   ^                                       ^                       ^
   |     Zero or more AES-128 chained      | hmacLength bytes long |
   +--------    cipher blocks   -----------+---  (may be zero)  ---+
        
   +----------------+     +----------------+~~~~~~~~~~~~~~~~~~~~~~~+
   |  CBC Block 1   | ... |  CBC Block N   |     truncatedHMAC     |
   +----------------+     +----------------+~~~~~~~~~~~~~~~~~~~~~~~+
   ^                                       ^                       ^
   |     Zero or more AES-128 chained      | hmacLength bytes long |
   +--------    cipher blocks   -----------+---  (may be zero)  ---+
        
   struct flashProfileEncryptedPacket_t
   {
       if(HMAC is being used)
           hmacLength = negotiated length;
       else
           hmacLength = 0;
        
   struct flashProfileEncryptedPacket_t
   {
       if(HMAC is being used)
           hmacLength = negotiated length;
       else
           hmacLength = 0;
        
       struct
       {
           iv[16 bytes] = { 0 };
           blockCount = 0;
           while((remainder() > hmacLength) && (remainder() >= 16))
           {
               uint8_t cbcBlock[16];
               blockCount++;
           }
       } chainedCipherBlocks :variable*16*8;
        
       struct
       {
           iv[16 bytes] = { 0 };
           blockCount = 0;
           while((remainder() > hmacLength) && (remainder() >= 16))
           {
               uint8_t cbcBlock[16];
               blockCount++;
           }
       } chainedCipherBlocks :variable*16*8;
        
       if(HMAC is being used)
       {
           if(remainder() == hmacLength)
               uint8_t truncatedHMAC[hmacLength];
           else
               packetVerificationFailed();
       }
       else if(remainder() > 0)
           packetVerificationFailed();
   } :encryptedPacket.length*8;
        
       if(HMAC is being used)
       {
           if(remainder() == hmacLength)
               uint8_t truncatedHMAC[hmacLength];
           else
               packetVerificationFailed();
       }
       else if(remainder() > 0)
           packetVerificationFailed();
   } :encryptedPacket.length*8;
        

cbcBlock: The next AES-128-CBC block.

CBC块:下一个AES-128-CBC块。

chainedCipherBlocks: The concatenation of every cipher block in the packet (over which the HMAC is computed).

chainedCipherBlocks:数据包中每个密码块的串联(HMAC是在其上计算的)。

truncatedHMAC: If HMAC was negotiated to be used (Section 4.5.2.4), this field is set to the first negotiated hmacLength bytes of the HMAC of the chainedCipherBlocks.

truncatedHMAC:如果HMAC是协商使用的(第4.5.2.4节),则此字段设置为ChainedCipherblock的HMAC的第一个协商hmacLength字节。

The plaintext data before encryption or after decryption has the following format:

加密前或解密后的明文数据具有以下格式:

    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +~~~~~~~~~~~~~/~+
   | SSEQ (opt.) \ |
   +~~~~~~~~~~~~~/~+
   +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+
   |        Checksum (opt.)        |
   +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                        Plain RTMFP Packet                     |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +~~~~~~~~~~~~~/~+
   | SSEQ (opt.) \ |
   +~~~~~~~~~~~~~/~+
   +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+
   |        Checksum (opt.)        |
   +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                        Plain RTMFP Packet                     |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   struct flashProfilePlainPacket_t
   {
       if(session sequence numbers being used)
           vlu_t sessionSequenceNumber :variable*8; // SSEQ
       if(HMAC not being used)
           uint16_t checksum;
       packet_t plainRTMFPPacket :variable*8;
   } :chainedCipherBlocks.blockCount*16*8;
        
   struct flashProfilePlainPacket_t
   {
       if(session sequence numbers being used)
           vlu_t sessionSequenceNumber :variable*8; // SSEQ
       if(HMAC not being used)
           uint16_t checksum;
       packet_t plainRTMFPPacket :variable*8;
   } :chainedCipherBlocks.blockCount*16*8;
        

sessionSequenceNumber: If session sequence numbers were negotiated to be used (Section 4.6.6), this field is present and is the VLU session sequence number of this packet.

sessionSequenceNumber:如果协商使用会话序列号(第4.6.6节),则此字段存在,并且是此数据包的VLU会话序列号。

checksum: If HMAC was not negotiated to be used, this field is present and is the simple checksum (Section 4.7.3.1) of the remaining bytes of this structure.

校验和:如果未协商使用HMAC,则此字段存在,并且是此结构剩余字节的简单校验和(第4.7.3.1节)。

plainRTMFPPacket: The (plain, unencrypted) RTMFP Packet (Section 2.2.4 of RFC 7016) plus any necessary padding.

plainRTMFPPacket:RTMFP数据包(普通、未加密)(RFC 7016第2.2.4节)加上任何必要的填充。

When assembling this structure and prior to calculating the checksum (if present), if the structure's total length is not an integer multiple of 16 bytes (the AES cipher block size), pad the end of plainRTMFPPacket with as many bytes having a value of 0xff as are needed to bring the structure's total length to an integer multiple of 16 bytes. The receiver's RTMFP Packet parser (Section 2.2.4 of RFC 7016) will consume this padding.

组装此结构时,在计算校验和(如果存在)之前,如果该结构的总长度不是16字节的整数倍(AES密码块大小),请在plainRTMFPPacket的末尾填充所需的0xff值的字节数,以使该结构的总长度达到16字节的整数倍。接收器的RTMFP数据包解析器(RFC 7016第2.2.4节)将使用该填充。

4.7.3. Verification
4.7.3. 验证

In RTMFP, the Cryptography Profile is responsible for packet verification. In this profile, packets are verified with an HMAC or a simple checksum, depending on the configuration of the endpoints, and optionally verified against replay or duplication using session sequence numbers. The simple checksum is inside the encrypted packet, so it becomes essentially a 16-bit cryptographic checksum.

在RTMFP中,加密配置文件负责数据包验证。在此配置文件中,根据端点的配置,使用HMAC或简单校验和来验证数据包,并可选地使用会话序列号针对重播或复制进行验证。简单校验和在加密数据包内,因此它本质上成为一个16位加密校验和。

4.7.3.1. Simple Checksum
4.7.3.1. 简单校验和

The simple checksum is the 16-bit ones' complement of the 16-bit ones' complement sum of all 16-bit (2 bytes in network byte order) words to be checked. If there are an odd number of bytes to be checked, then for purposes of this checksum, treat the last byte as the lower 8 bits of a 16-bit word whose upper 8 bits are 0. This is also known as the "Internet Checksum" [RFC1071].

简单校验和是要检查的所有16位(网络字节顺序为2字节)字的16位1的补码和的16位1的补码。如果要检查的字节数为奇数,则出于此校验和的目的,将最后一个字节视为16位字的下8位,其上8位为0。这也称为“互联网校验和”[RFC1071]。

When present, the checksum is calculated over all bytes of the plaintext packet starting after the checksum field through the end of the plain packet. It cannot be calculated until the plain packet is padded, if necessary, to bring its length to an integer multiple of 16 bytes (the AES cipher block size). The session sequence number field, if present, and the checksum field itself are not included in the checksum.

当存在时,从校验和字段之后开始,直到纯文本数据包结束,对纯文本数据包的所有字节计算校验和。如果需要,在对普通数据包进行填充以使其长度达到16字节的整数倍(AES密码块大小)之前,无法计算它。会话序列号字段(如果存在)和校验和字段本身不包括在校验和中。

On receiving a packet being verified with a checksum: calculate the checksum over all the bytes of the plaintext packet following the checksum field and compare the checksum to the value in the checksum field. If they match, the packet is verified; if they do not match, the packet is corrupt and MUST be discarded as though it was never received.

在接收到使用校验和验证的数据包时:计算校验和字段后面的明文数据包的所有字节的校验和,并将校验和与校验和字段中的值进行比较。如果它们匹配,则验证数据包;如果它们不匹配,则数据包已损坏,必须丢弃,就像从未收到一样。

4.7.3.2. HMAC
4.7.3.2. HMAC

When present, the HMAC field is the last hmacLength bytes of the packet and is calculated over all of the encrypted cipher blocks of the packet preceding the HMAC field. The value of the HMAC field is the first hmacLength bytes of the HMAC-SHA256 of the checked data, using the computed HMAC keys (Section 4.6.4) and negotiated hmacLength (Section 4.5.2.4). Note each endpoint independently specifies the length of the HMAC it will send via its hmacLength field.

当存在时,HMAC字段是数据包的最后一个HMAC长度字节,并在HMAC字段之前的数据包的所有加密密码块上进行计算。HMAC字段的值是使用计算的HMAC密钥(第4.6.4节)和协商的hmacLength(第4.5.2.4节)检查数据的HMAC-SHA256的第一个hmacLength字节。注意:每个端点独立地指定它将通过其hmacLength字段发送的HMAC的长度。

When an endpoint has negotiated to send an HMAC, it encrypts the data blocks, computes the HMAC over the encrypted data blocks using its HMAC_SEND_KEY, and appends the first hmacLength bytes of that hash after the final encrypted data block.

当端点协商发送HMAC时,它会加密数据块,使用其HMAC_send_密钥计算加密数据块上的HMAC,并在最终加密数据块后附加该哈希的第一个HMA长度字节。

When an endpoint has negotiated to receive an HMAC, the endpoint computes the HMAC over the encrypted data blocks using its HMAC_RECV_KEY and then compares the first receive hmacLength bytes of the computed HMAC to the HMAC field in the packet. If they are identical, the packet is verified; if they are not identical, the packet is corrupt and MUST be discarded as though it was never received.

当端点协商接收HMAC时,端点使用其HMAC_RECV_密钥计算加密数据块上的HMAC,然后将计算出的HMAC的第一个接收HMAC长度字节与数据包中的HMAC字段进行比较。如果它们相同,则验证数据包;如果它们不相同,则数据包已损坏,必须丢弃,就像从未收到一样。

HMAC and simple checksum verification are mutually exclusive.

HMAC和简单校验和验证是互斥的。

4.7.3.3. Session Sequence Number
4.7.3.3. 会话序列号

Session sequence numbers are used to detect and reject a packet that was duplicated in the network or replayed by an attacker and to ensure the first chained cipher block of every packet is unique, in lieu of a full-block initialization vector. Sequence numbers start at zero, increase by one for each packet sent in the session, do not wrap, and do not repeat.

会话序列号用于检测和拒绝在网络中复制或被攻击者重播的数据包,并确保每个数据包的第一个链式密码块是唯一的,而不是完整的块初始化向量。序列号从零开始,会话中发送的每个数据包增加一个,不包装,也不重复。

When session sequence numbers are negotiated to be used, the receiver MUST allow for packets to be reordered in the network by up to at least 32 sequence numbers; note, however, that reordering by more than three packets can trigger loss detection and retransmission by negative acknowledgement, just as with TCP, and is therefore not likely to occur in the real Internet.

当会话序列号被协商使用时,接收器必须允许分组在网络中被重新排序至少32个序列号;然而,请注意,与TCP一样,通过三个以上的数据包重新排序可以触发丢失检测并通过否定确认进行重新传输,因此在真实的Internet中不太可能发生这种情况。

[RFC4302], [RFC4303], and [RFC6479] describe Anti-Replay Window methods that can be employed to detect duplicate sequence numbers. Other methods are possible.

[RFC4302]、[RFC4303]和[RFC6479]描述了可用于检测重复序列号的反重播窗口方法。其他方法也是可能的。

Any packet received having a session sequence number that was already seen in that session, either directly or by being less than the lowest sequence number in the Anti-Replay Window, is a duplicate and MUST be discarded as though never received.

任何接收到的具有会话序列号的数据包(直接或通过小于反重播窗口中的最低序列号)都是重复的,必须丢弃,就像从未接收到一样。

5. Flash Communication
5. 闪光通信

The Flash platform uses RTMP [RTMP] messages for media streaming and communication. This section describes how to transport RTMP messages over RTMFP flows and additional messages and semantics unique to this transport.

Flash平台使用RTMP[RTMP]消息进行媒体流和通信。本节介绍如何通过RTMFP流传输RTMP消息以及此传输特有的其他消息和语义。

5.1. RTMP Messages
5.1. RTMP消息

An RTMP message comprises a virtual header and a payload. The virtual header comprises a Message Type, a Payload Length, a Timestamp, and a Stream ID. The format of the payload is dependent on the type of message.

An RTMP message comprises a virtual header and a payload. The virtual header comprises a Message Type, a Payload Length, a Timestamp, and a Stream ID. The format of the payload is dependent on the type of message.translate error, please retry

An RTMP message is mapped onto a lower transport layer, such as RTMP Chunk Stream [RTMP] or RTMFP. RTMP messages were initially designed along with, and for transport on, RTMP Chunk Stream. This design constrains the possible values of RTMP message header fields. In particular:

RTMP消息映射到较低的传输层,例如RTMP区块流[RTMP]或RTMFP。RTMP消息最初是与RTMP区块流一起设计的,并用于在RTMP区块流上传输。此设计限制RTMP消息头字段的可能值。特别地:

Message Type is 8 bits wide, and is therefore constrained to values from 0 to 255 inclusive;

消息类型为8位宽,因此限制为0到255(含0到255)的值;

Payload Length is 24 bits wide, so messages can be at most 16777215 bytes long;

有效负载长度为24位宽,因此消息的长度最多为16777215字节;

Timestamp is 32 bits wide, so timestamps range from 0 to 4294967295 and wrap around;

时间戳是32位宽,所以时间戳的范围从0到4294967295,并环绕;

Stream ID is 24 bits wide, and is therefore constrained to values from 0 to 16777215 inclusive.

流ID为24位宽,因此被限制为0到16777215(包括0到16777215)的值。

RTMP Chunk Stream Protocol Control messages (message types 1, 2, 3, 5, and 6) are not used when transporting RTMP messages in RTMFP flows. Messages of those types SHOULD NOT be sent and MUST be ignored.

在RTMFP流中传输RTMP消息时,不使用RTMP区块流协议控制消息(消息类型1、2、3、5和6)。这些类型的消息不应发送,必须忽略。

5.1.1. Flow Metadata
5.1.1. 流元数据

All messages in RTMFP are transported in flows. In this profile, an RTMFP flow for RTMP messages carries the messages for exactly one RTMP Stream ID. Multiple flows can carry messages for the same Stream ID; for example, the video and audio messages of a stream could be sent on separate flows, allowing the audio to be given higher transmission priority.

RTMFP中的所有消息都在流中传输。在该配置文件中,RTMP消息的RTMFP流只携带一个RTMP流ID的消息。多个流可以携带相同流ID的消息;例如,流的视频和音频消息可以在单独的流上发送,从而允许赋予音频更高的传输优先级。

The User Metadata for flows in this profile begins with a distinct signature to distinguish among different kinds of flows. The User Metadata for a flow used for RTMP messages begins with the two-character signature "TC".

此概要文件中流的用户元数据以不同的签名开始,以区分不同类型的流。用于RTMP消息的流的用户元数据以两个字符的签名“TC”开头。

The Stream ID is encoded in the flow's User Metadata so that it doesn't need to be sent with each message.

流ID编码在流的用户元数据中,因此不需要随每条消息一起发送。

The sender can have a priori knowledge about the kind of media it intends to send on a flow and its intended use and can give the receiver a hint as to whether messages should be delivered as soon as possible or in their original queuing order. For example, the sender might be sending real-time, delay-sensitive audio messages on a flow, and hint that the receiver should take delivery of the messages on that flow as soon as they arrive in the network, to reduce the end-to-end latency of the audio.

发送方可以事先知道它打算在流上发送的媒体类型及其预期用途,并且可以向接收方提示消息是应该尽快发送还是按照原始排队顺序发送。例如,发送方可能正在流上发送实时、延迟敏感的音频消息,并提示接收方在消息到达网络后应立即接收该流上的消息,以减少音频的端到端延迟。

The receiver can choose to take delivery of messages on flows as soon as they arrive in the network or in the messages' original queuing order. A receiver that chooses to take delivery of messages as soon as they arrive in the network MUST be prepared for the messages to

接收方可以选择在消息流到达网络或消息的原始排队顺序时立即在流上接收消息。选择在消息到达网络后立即接收消息的接收者必须为消息的发送做好准备

arrive out-of-order. For example, a receiver may choose not to render a newly received audio message having a timestamp earlier than the most recently rendered audio timestamp.

出故障了。例如,接收机可以选择不呈现时间戳早于最近呈现的音频时间戳的新接收的音频消息。

The sender can choose to abandon a message that it has queued in a flow before the message has been delivered to the receiver. For example, the sender may abandon a real-time, delay-sensitive audio message that has not been delivered within one second, to avoid spending transmission resources on stale media that is no longer relevant.

发送方可以选择放弃在消息传递给接收方之前已在流中排队的消息。例如,发送方可以放弃在一秒钟内没有传递的实时、延迟敏感的音频消息,以避免在不再相关的陈旧媒体上花费传输资源。

Note: A gap will cause a delay at the receiver of at least one round-trip time if the receiver is taking delivery of messages in original queuing order.

注意:如果接收方按照原始排队顺序接收消息,则间隔将导致接收方至少延迟一个往返时间。

    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+~~~~~~~~~~~~~/~+
   |               |               |         |S|r|R|             \ |
   |   0x54  'T'   |   0x43  'C'   |   rsv   |I|s|X|   streamID  / |
   |               |               |         |D|v|I|             \ |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+~~~~~~~~~~~~~/~+
        
    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+~~~~~~~~~~~~~/~+
   |               |               |         |S|r|R|             \ |
   |   0x54  'T'   |   0x43  'C'   |   rsv   |I|s|X|   streamID  / |
   |               |               |         |D|v|I|             \ |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+~~~~~~~~~~~~~/~+
        
   struct RTMPMetadata_t
   {
       uint8_t signature[2] == { 'T', 'C' };
       uintn_t reserved1       :5; // rsv
       bool_t  streamIDPresent :1; // SID
       uintn_t reserved2       :1; // rsv
       uintn_t receiveIntent   :1; // RXI
           // 0: original queuing order, 1: network arrival order
       if(streamIDPresent)
           vlu_t   streamID        :variable*8;
   } :variable*8;
        
   struct RTMPMetadata_t
   {
       uint8_t signature[2] == { 'T', 'C' };
       uintn_t reserved1       :5; // rsv
       bool_t  streamIDPresent :1; // SID
       uintn_t reserved2       :1; // rsv
       uintn_t receiveIntent   :1; // RXI
           // 0: original queuing order, 1: network arrival order
       if(streamIDPresent)
           vlu_t   streamID        :variable*8;
   } :variable*8;
        

signature: Metadata signature for RTMP message flows, being the two UTF-8 coded characters "TC".

签名:RTMP消息流的元数据签名,是两个UTF-8编码字符“TC”。

streamIDPresent: A boolean flag indicating whether the streamID field is present. In this profile, this flag MUST be set.

streamIDPresent:一个布尔标志,指示streamID字段是否存在。在此配置文件中,必须设置此标志。

receiveIntent: A hint by the sender as to the best order in which to take delivery of messages from the flow. A value of zero indicates a hint that the flow's messages should be received in the order they were originally queued by the sender (that is, in ascending sequence number order); a value of one indicates a hint that the flow's messages should be received in the order they arrive in the network, even if there are sequence number gaps or reordering. Network arrival order is typically hinted for live,

receiveIntent:发送方关于从流中接收消息的最佳顺序的提示。值为零表示流的消息应按发送方最初排队的顺序接收(即,按升序顺序);值为1表示流的消息应按其到达网络的顺序接收的提示,即使存在序列号间隙或重新排序。网络到达订单通常为实时提示,

delay-sensitive flows, such as for audio media. To take delivery of a message as soon as it arrives in the network: receive it from the receiving flow's RECV_BUFFER as soon as it becomes complete (Section 3.6.3.3 of RFC 7016), and remove it from the RECV_BUFFER. Section 3.6.3.3 of RFC 7016 describes how to take delivery of messages in original queuing order.

延迟敏感流,如音频媒体。消息到达网络后立即接收消息:消息完成后立即从接收流的RECV_缓冲区接收消息(RFC 7016第3.6.3.3节),并将其从RECV_缓冲区移除。RFC 7016第3.6.3.3节描述了如何按照原始排队顺序接收消息。

streamID: If the streamIDPresent flag is set, this field is present and is the RTMP stream ID to which the messages in this flow belong. In this profile, this field MUST be present.

streamID:如果设置了streamIDPresent标志,则此字段存在,并且是此流中的消息所属的RTMP流ID。在此配置文件中,此字段必须存在。

A receiver SHOULD reject an RTMP message flow if its streamIDPresent flag is clear. This profile doesn't define a stream mapping for this case.

如果RTMP消息流的streamIDPresent标志清除,则接收方应拒绝该消息流。此配置文件没有为此情况定义流映射。

Derived or composed profiles can define additional flow types and corresponding metadata signatures. A receiver SHOULD reject a flow having an unrecognized metadata signature.

派生或组合的概要文件可以定义其他流类型和相应的元数据签名。接收方应拒绝具有无法识别的元数据签名的流。

5.1.2. Message Mapping
5.1.2. 消息映射

This section describes the format of an RTMP message (Section 5.1) in an RTMFP flow.

本节描述RTMFP流中RTMP消息的格式(第5.1节)。

    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+
   |  messageType  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                           timestamp                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                         messagePayload                        |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+
   |  messageType  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                           timestamp                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                         messagePayload                        |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
        
   struct RTMPMessage_t
   {
       uint8_t  messageType;
       uint32_t timestamp;
       uint8_t  messagePayload[remainder()];
   } :flowMessageLength*8;
        
   struct RTMPMessage_t
   {
       uint8_t  messageType;
       uint32_t timestamp;
       uint8_t  messagePayload[remainder()];
   } :flowMessageLength*8;
        

messageType: The RTMP Message Type;

messageType:RTMP消息类型;

timestamp: The RTMP Timestamp, in network byte order;

时间戳:RTMP时间戳,以网络字节顺序表示;

messagePayload: The payload of the RTMP message;

messagePayload:RTMP消息的有效负载;

payload length: The RTMP message payload length is inferred from the length of the RTMFP message;

有效负载长度:根据RTMFP消息的长度推断RTMP消息有效负载长度;

Stream ID: The Stream ID for this message is taken from the metadata of the flow on which this message was received.

流ID:此消息的流ID取自接收此消息的流的元数据。

5.2. Flow Synchronization
5.2. 流同步

RTMFP flows are independent and have no inter-flow ordering guarantee. RTMP was designed for transport over a single, reliable, strictly ordered byte stream. Some RTMP message semantics take advantage of this ordering; for example, a Stream EOF User Control event must not be processed until after all media messages for the corresponding stream have been received. Flow Synchronization messages provide a barrier to align message delivery across flows when required by RTMP semantics.

RTMFP流是独立的,没有流间顺序保证。RTMP设计用于通过单个、可靠、严格排序的字节流进行传输。一些RTMP消息语义利用了这种顺序;例如,在收到相应流的所有媒体消息之前,不得处理流EOF用户控制事件。当RTMP语义需要时,流同步消息提供了跨流对齐消息传递的屏障。

A Flow Synchronization message is coded as a User Control event message (Type 4) having Event Type 34. Message timestamps are ignored and MAY be set to 0.

流同步消息被编码为具有事件类型34的用户控制事件消息(类型4)。消息时间戳被忽略,并且可以设置为0。

    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+
   |       4       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                           timestamp                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         eventType = 34        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             syncID                            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             count                             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        
    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+
   |       4       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                           timestamp                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         eventType = 34        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             syncID                            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             count                             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        
   struct flowSyncUserControlMessagePayload_t
   {
       uint16_t eventType = 34;
       uint32_t syncID;
       uint32_t count;
   } :10*8;
        
   struct flowSyncUserControlMessagePayload_t
   {
       uint16_t eventType = 34;
       uint32_t syncID;
       uint32_t count;
   } :10*8;
        

eventType: The RTMP User Control Message Event Type. Flow Synchronization messages have type 34 (0x22);

eventType:RTMP用户控制消息事件类型。流同步消息的类型为34(0x22);

syncID: The identifier for this barrier;

syncID:此屏障的标识符;

count: The number of flows being synchronized by syncID. This field MUST be at least 1 and SHOULD be at least 2.

计数:通过syncID同步的流数。此字段必须至少为1,并且应至少为2。

On receipt of a Flow Synchronization message, a receiver SHOULD suspend receipt of further messages on that flow until count Flow Synchronization messages (including this one) with the same syncID have been received on flows in the same flow association tree.

在接收到流同步消息时,接收方应暂停接收该流上的其他消息,直到在同一流关联树中的流上接收到具有相同syncID的计数流同步消息(包括此消息)。

Example: Consider flows F1 and F2 in the same NetConnection carrying messages M, and let Sync(syncID,count) denote a Flow Synchronization message.

示例:考虑在携带消息M的同一网络连接中的流F1和F2,并让Syc(SycID,Calt)表示流同步消息。

                                       |                |
             F1: M1  M2  M4  Sync(8,2) | Sync(13,2).....| M7
                                       |                |
             F2:   M3  Sync(8,2).......| M5  Sync(13,2) | M6
                                       |                |
                                   Barrier 8        Barrier 13
        
                                       |                |
             F1: M1  M2  M4  Sync(8,2) | Sync(13,2).....| M7
                                       |                |
             F2:   M3  Sync(8,2).......| M5  Sync(13,2) | M6
                                       |                |
                                   Barrier 8        Barrier 13
        

Figure 2: Example Flow Synchronization Barriers

图2:流同步屏障示例

Flow Synchronization messages form a delivery barrier to impart at least a partial message ordering across flows. In this example, message M5 comes after M1..4 and before M6..7; however, M3 could be delivered before or after any of M1, M2, or M4, and M6 could come before or after M7.

流同步消息形成传递屏障,以在流之间传递至少部分消息顺序。在本例中,消息M5位于M1..4之后,M6..7之前;但是,M3可以在M1、M2或M4中的任何一个之前或之后交付,而M6可以在M7之前或之后交付。

Flow Synchronization can cause a priority inversion; therefore, it SHOULD NOT be used except when necessary to preserve RTMP ordering semantics.

流同步可能导致优先级反转;因此,除非有必要保留RTMP排序语义,否则不应使用它。

5.3. Client-to-Server Connection
5.3. 客户端到服务器的连接

The client connects to a server. The connection comprises one main control flow in each direction from client to server and from server to client for NetConnection messages, and zero or more flows in each direction for NetStream media messages. NetStream flows may come and go naturally over time according to media transport needs. An exception on a NetConnection control sending flow indicates the closure by the other end of the NetConnection and all associated NetStreams.

客户端连接到服务器。对于NetConnection消息,连接包括在每个方向上从客户端到服务器和从服务器到客户端的一个主控制流,以及在每个方向上为NetStream媒体消息提供零个或多个流。根据媒体传输需求,NetStream流可能会随着时间的推移而自然变化。NetConnection控件发送流上的异常表示NetConnection的另一端和所有关联的NetStream关闭。

The client MUST NOT use the same client certificate for more than one server connection; that is, a client's peer ID MUST NOT be reused.

客户端不能对多个服务器连接使用同一客户端证书;也就是说,不能重用客户端的对等ID。

5.3.1. Connecting
5.3.1. 连接

The client desires a connection to a server having an RTMFP URI, for example, "rtmfp://server.example.com/app/instance". The client gathers one or more initial candidate addresses for the server named in the URI (for example, by using the Domain Name System (DNS)

例如,客户端希望连接到具有RTMFP URI的服务器,“rtmfp://server.example.com/app/instance". 客户端为URI中命名的服务器收集一个或多个初始候选地址(例如,通过使用域名系统(DNS))

[RFC1035]). The client creates an EPD having an Ancillary Data option (Section 4.4.2.2) encoding the URI. The client initiates an RTMFP session to the one or more candidate addresses using the EPD.

[RFC1035])。客户端创建一个具有辅助数据选项(第4.4.2.2节)的EPD,该选项对URI进行编码。客户端使用EPD向一个或多个候选地址发起RTMFP会话。

When the session transitions to the S_OPEN state, the client opens a new flow in that session for Stream ID 0 and Receive Intent 0 "original queuing order". This is the client's NetConnection main control flow. The client sends an RTMP "connect" command on the flow and waits for a response or exception.

当会话转换到S_打开状态时,客户端在该会话中为流ID 0和接收意图0“原始排队顺序”打开一个新流。这是客户端的NetConnection主控制流。客户端在流上发送RTMP“connect”命令,并等待响应或异常。

5.3.2. Server-to-Client Return Control Flow
5.3.2. 服务器到客户端返回控制流

The server, on accepting the client's NetConnection control flow, and receiving and accepting the "connect" command, opens one or more return flows to the client having Stream ID 0 and associated to the control flow from the client. Flows for Stream ID 0 are the server's NetConnection control flows. The server sends a "_result" or "_error" transaction response for the client's connect command.

服务器在接受客户端的NetConnection控制流并接收和接受“connect”命令时,会打开一个或多个返回流,返回流ID为0且与来自客户端的控制流关联的客户端。流ID 0的流是服务器的网络连接控制流。服务器为客户端的connect命令发送“\u结果”或“\u错误”事务响应。

When the client receives the first return flow from the server for Stream ID 0 and associated to the client's NetConnection control flow, the client assumes that flow is the canonical return NetConnection control flow from the server, to which all new client-to-server flows should be associated.

当客户端从服务器接收到流ID为0的第一个返回流并与客户端的NetConnection控制流相关联时,客户端假定该流是来自服务器的规范返回NetConnection控制流,所有新的客户端到服务器流都应与之相关联。

On receipt of a "_result" transaction response on Stream ID 0 for the client's connect command, the connection is up.

在收到客户端connect命令的流ID 0上的“_result”事务响应时,连接启动。

The client MAY open additional return control flows to the server on Stream ID 0, associated to the server's canonical NetConnection control flow.

客户端可以在流ID为0的服务器上打开其他返回控制流,该流与服务器的规范NetConnection控制流关联。

5.3.3. setPeerInfo Command
5.3.3. setPeerInfo命令

The "setPeerInfo" command is sent by the client to the server over the NetConnection control flow to inform the server of candidate socket addresses through which the client might be reachable. This list SHOULD include all directly connected interface addresses and proxy addresses except as provided below. The list MAY be empty. The list need not include the address of the server, even if the server is to act as an introducer for the client. The list SHOULD NOT include link-local or loopback addresses.

“setPeerInfo”命令由客户机通过NetConnection控制流发送到服务器,以通知服务器可以访问客户机的候选套接字地址。该列表应包括所有直接连接的接口地址和代理地址,以下提供的除外。列表可能为空。该列表不需要包括服务器的地址,即使服务器将充当客户机的介绍人。该列表不应包括链接本地或环回地址。

This command is sent as a regular RTMP NetConnection command; that is, as an RTMP Type 20 Command Message or an RTMP Type 17 Command Extended Message on Stream ID 0. A Type 20 Command Message SHOULD be used if the object encoding negotiated during the "connect" and

此命令作为常规RTMP NetConnection命令发送;即,作为流ID 0上的RTMP类型20命令消息或RTMP类型17命令扩展消息。如果在“连接”过程中协商对象编码,则应使用类型20命令消息,并且

"_result" handshake is AMF0 [AMF0], and a Type 17 Command Extended Message SHOULD be used if the negotiated object encoding is AMF3 [AMF3].

“_result”握手为AMF0[AMF0],如果协商对象编码为AMF3[AMF3],则应使用类型17命令扩展消息。

Note: A Type 20 Command Message payload is a sequence of AMF objects encoded in AMF0.

注:类型20命令消息有效负载是AMF0中编码的AMF对象序列。

Note: A Type 17 Command Extended Message payload begins with a format selector byte, followed by a sequence of objects in a format-specific encoding. At the time of writing, only format 0 is defined; therefore, the format selector byte MUST be 0. Format 0 is a sequence of AMF objects, each encoded in AMF0 by default; AMF3 encoding for an object can be selected by prefixing it with an "avmplus-object-marker" (0x11) as defined in [AMF0].

注意:类型17命令扩展消息有效负载以格式选择器字节开始,后跟特定于格式的编码中的一系列对象。在编写本文时,仅定义了格式0;因此,格式选择器字节必须为0。格式0是AMF对象的序列,默认情况下每个对象都以AMF0编码;对象的AMF3编码可以通过使用[AMF0]中定义的“avmplus对象标记”(0x11)作为前缀来选择。

To complete the RTMFP NetConnection handshake, an RTMFP client MUST send a setPeerInfo command to the server after receiving a successful response to the "connect" command.

要完成RTMFP NetConnection握手,RTMFP客户端必须在收到对“connect”命令的成功响应后向服务器发送setPeerInfo命令。

   (
       "setPeerInfo", // AMF String, command name
       0.0,  // AMF Number, transaction ID
       NULL, // AMF Null, no command object
       ...   // zero or more AMF Strings, each an address
   )
        
   (
       "setPeerInfo", // AMF String, command name
       0.0,  // AMF Number, transaction ID
       NULL, // AMF Null, no command object
       ...   // zero or more AMF Strings, each an address
   )
        

Each listed socket address includes an IPv4 or IPv6 address in presentation format and a UDP port number in decimal, separated by a colon. Since the IPv6 address presentation format uses colons, IPv6 addresses are enclosed in square brackets [RFC3986].

列出的每个套接字地址包括一个表示格式的IPv4或IPv6地址和一个十进制UDP端口号(用冒号分隔)。由于IPv6地址表示格式使用冒号,因此IPv6地址用方括号括起来[RFC3986]。

( "setPeerInfo", 0.0, NULL, "192.0.2.129:50001", "[2001:db8:1::2]:50002" )

(“setPeerInfo”,0.0,NULL,“192.0.2.129:50001”,“[2001:db8:1::2]:50002”)

Figure 3: Example setPeerInfo Command

图3:setPeerInfo命令示例

A server SHOULD assume that the client is behind a Network Address Translator (NAT) if and only if the observed far endpoint address of the session for the flow on which this command was received does not appear in the setPeerInfo address list.

当且仅当接收到此命令的流的会话的观察到的远端端点地址未出现在setPeerInfo地址列表中时,服务器应假定客户端位于网络地址转换器(NAT)后面。

5.3.4. Set Keepalive Timers Command
5.3.4. 设置保留计时器命令

The server can advise the client to set or change the client's session keepalive timer periods for its connection to the server and for its P2P connections. The server MAY choose keepalive periods based on static configuration, application- or deployment-specific circumstances, whether the client appears to be behind a NAT, or for any other reason.

服务器可以建议客户端为其与服务器的连接和P2P连接设置或更改客户端的会话keepalive计时器周期。服务器可以根据静态配置、特定于应用程序或部署的环境、客户端是否处于NAT之后或出于任何其他原因选择保留期。

The Set Keepalive Timers command is sent by the server to the client on Stream ID 0 as a User Control event message (Type 4) having Event Type 41. Message timestamps are ignored and MAY be set to 0.

服务器将Set Keepalive Timers命令作为事件类型为41的用户控件事件消息(类型4)发送到流ID为0的客户端。消息时间戳被忽略,并且可以设置为0。

    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+
   |       4       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                           timestamp                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         eventType = 41        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    serverKeepalivePeriodMsec                  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                     peerKeepalivePeriodMsec                   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        
    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+
   |       4       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                           timestamp                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         eventType = 41        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    serverKeepalivePeriodMsec                  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                     peerKeepalivePeriodMsec                   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        
   struct setKeepaliveUserControlMessagePayload_t
   {
       uint16_t eventType = 41;
       uint32_t serverKeepalivePeriodMsec;
       uint32_t peerKeepalivePeriodMsec;
   } :10*8;
        
   struct setKeepaliveUserControlMessagePayload_t
   {
       uint16_t eventType = 41;
       uint32_t serverKeepalivePeriodMsec;
       uint32_t peerKeepalivePeriodMsec;
   } :10*8;
        

eventType: The RTMP User Control Message Event Type. Set Keepalive Timers messages have type 41 (0x29);

eventType:RTMP用户控制消息事件类型。Set Keepalive Timers消息的类型为41(0x29);

serverKeepalivePeriodMsec: The keepalive period, in milliseconds, that the client is advised to set on its RTMFP session with the server;

serverKeepalivePeriodMsec:建议客户端在与服务器的RTMFP会话中设置的keepalive周期(以毫秒为单位);

peerKeepalivePeriodMsec: The keepalive period, in milliseconds, that the client is advised to use on its RTMFP sessions with any peer that is not the server.

PeerkePaLivePeriodMsec:建议客户端在与非服务器的任何对等方的RTMFP会话中使用的keepalive期间(以毫秒为单位)。

The client MUST define minimum values for these keepalive periods, below which it will not set them, regardless of the values in this message. The minimum keepalive timer periods SHOULD be at least five seconds. The client MAY define maximum values for these keepalive periods, above which it will not set them.

客户端必须为这些保持期定义最小值,低于该值时,无论此消息中的值如何,客户端都不会设置这些值。保持活动计时器的最小周期应至少为5秒。客户机可能会为这些保留期定义最大值,超过该值则不会设置它们。

On receipt of this message from the server, a client SHOULD set its RTMFP server and peer keepalive timer periods to the indicated values subject to the client's minimum and maximum values. The server MAY send this message more than once, particularly if conditions that it uses to determine the timer periods change.

从服务器收到此消息后,客户机应根据客户机的最小值和最大值,将其RTMFP服务器和对等方keepalive计时器周期设置为指示值。服务器可能会多次发送此消息,尤其是当用于确定计时器周期的条件发生变化时。

5.3.5. Additional Flows for Streams
5.3.5. 流的附加流

The client or server opens additional flows to the other side to carry messages for any stream. Additional flows are associated to the canonical NetConnection control flow from the other side.

客户端或服务器向另一端打开额外的流,以承载任何流的消息。其他流与另一端的规范NetConnection控制流相关联。

         Client                                            Server
         ------>--C2S-Control-Flow------------------------->--+
                                                              |
            +--<------------------------S2C-Control-Flow---<--+
            |                                                 |
            |  <------------------------S2C-Stream-Flow-1--<--+
            |                                  :              |
            |  <------------------------S2C-Stream-Flow-M--<--+
            |
            +-->--C2S-Stream-Flow-1------------------------>
            |               :
            +-->--C2S-Stream-Flow-N------------------------>
        
         Client                                            Server
         ------>--C2S-Control-Flow------------------------->--+
                                                              |
            +--<------------------------S2C-Control-Flow---<--+
            |                                                 |
            |  <------------------------S2C-Stream-Flow-1--<--+
            |                                  :              |
            |  <------------------------S2C-Stream-Flow-M--<--+
            |
            +-->--C2S-Stream-Flow-1------------------------>
            |               :
            +-->--C2S-Stream-Flow-N------------------------>
        

Figure 4: Schematic Flow Association Tree for a NetConnection

图4:网络连接的流程关联树示意图

5.3.5.1. To Server
5.3.5.1. 到服务器

Additional flows from the client to the server for stream messages are opened with the Stream ID for that stream and associated in return to the server's canonical NetConnection control flow.

从客户端到服务器的流消息的附加流将使用该流的流ID打开,并关联到服务器的规范NetConnection控制流。

The client MAY create as many flows as desired for any Stream ID (including Stream ID 0) at any time.

客户机可以在任何时间为任何流ID(包括流ID 0)创建所需数量的流。

5.3.5.2. From Server
5.3.5.2. 从服务器

Additional flows from the server to the client for stream messages are opened with the Stream ID for that stream, and associated in return to the client's NetConnection control flow.

对于流消息,从服务器到客户端的其他流将使用该流的流ID打开,并与客户端的NetConnection控制流相关联。

The server MAY create as many flows as desired for any Stream ID (including Stream ID 0) at any time.

服务器可以随时为任何流ID(包括流ID 0)创建所需数量的流。

5.3.5.3. Closing Stream Flows
5.3.5.3. 截流

Either end MAY close a sending flow that is not for Stream ID 0 at any time with no semantic meaning for the stream.

任何一端都可以随时关闭不适用于流ID 0的发送流,而该流没有语义含义。

At any time, either end MAY reject a receiving flow that is not one of the other end's NetConnection control flows. No flow exception codes are defined by this profile, so the receiving end SHOULD use exception code 0 when rejecting the flow. The sending end, on notification of any exception for a stream flow, SHOULD NOT open a new flow to take the rejected flow's place for transport of messages for that stream. If an end rejects any flow for a stream, it SHOULD reject all the flows for that stream, otherwise Flow Synchronization messages (Section 5.2) that were in flight could be discarded and some flows might become or remain stuck in a suspended state.

在任何时候,任何一端都可以拒绝不是另一端的NetConnection控制流之一的接收流。此配置文件未定义任何流异常代码,因此接收端在拒绝流时应使用异常代码0。发送端在收到流的任何异常通知时,不应打开新的流来代替被拒绝的流来传输该流的消息。如果终端拒绝某个流的任何流,它应该拒绝该流的所有流,否则可能会丢弃正在传输的流同步消息(第5.2节),并且一些流可能会变成或保持挂起状态。

5.3.6. Closing the Connection
5.3.6. 关闭连接

The client or server can signal an orderly close of the connection by closing its NetConnection control sending flows and all stream sending flows. The other end, on receiving a close/complete notification for the canonical NetConnection control receiving flow, closes its sending flows. When both ends observe all receiving flows have closed and completed, the connection has cleanly terminated.

客户端或服务器可以通过关闭其NetConnection控制发送流和所有流发送流来发出有序关闭连接的信号。另一端在接收到规范NetConnection控件接收流的关闭/完成通知时,关闭其发送流。当两端观察到所有接收流已关闭并完成时,连接已干净终止。

Either end can abruptly terminate the connection by rejecting the NetConnection control receiving flows or by closing the underlying RTMFP session. On notification of any exception on a NetConnection control sending flow, the end seeing the exception knows the other end has terminated abruptly, and can immediately close all sending and receiving flows for that connection.

任何一端都可以通过拒绝NetConnection控制接收流或关闭底层RTMFP会话来突然终止连接。在NetConnection控制发送流上通知任何异常时,看到异常的一端知道另一端已突然终止,并且可以立即关闭该连接的所有发送和接收流。

5.3.7. Example
5.3.7. 实例
                 Client                    Server
                   |IHello (EPD:anc=URI)     |
               -+- |------------------------>|
                |  |                         |
                |  |       RHello (RCert:anc)|
          RTMFP |  |<------------------------|
         Session|  |                         |
          Hand- |  |IIKeying                 |
          shake |  |------------------------>|
                |  |                         |
                |  |                 RIKeying|
               -+- |<------------------------|
                   |                         |
               -+- |"connect" command        |
         (Str.ID=0)|-CFlow-0---------------->|
                |  |                         |
                |  |       "_result" response|
          RTMP  |  |<----------------SFlow-0-|(Str.ID=0,
         Connect|  |                         | Assoc=CFlow-0)
          Hand- |  |"setPeerInfo" command    |
          shake |  |-CFlow-0---------------->|
               -+- |                         |
                   |"createStream" command   |
               -+- |-CFlow-0---------------->|
                |  |                         |
                |  |     "_result" (str.ID=5)|
                |  |<----------------SFlow-0-|
                |  |                         |
                |  |"play" command           |
         (Str.ID=5,|-CFlow-1---------------->|
     Assoc=SFlow-0)|                         |
                |  | StreamBegin User Control|
                |  |<----------------SFlow-1-|(Str.ID=5,
                |  |                         | Assoc=CFlow-0)
                |  |  (RTMP stream events)   |
     Streaming  |  |<----------------SFlow-1-|
                |  |                         |
                |  |        Audio Data       |
                |  |<----------------SFlow-2-|(Str.ID=5,
                |  |                         | Assoc=CFlow-0)
                |  |        Video Data       |
                |  |<----------------SFlow-3-|(Str.ID=5,
                |  |            :            | Assoc=CFlow-0)
                   |            :            |
        
                 Client                    Server
                   |IHello (EPD:anc=URI)     |
               -+- |------------------------>|
                |  |                         |
                |  |       RHello (RCert:anc)|
          RTMFP |  |<------------------------|
         Session|  |                         |
          Hand- |  |IIKeying                 |
          shake |  |------------------------>|
                |  |                         |
                |  |                 RIKeying|
               -+- |<------------------------|
                   |                         |
               -+- |"connect" command        |
         (Str.ID=0)|-CFlow-0---------------->|
                |  |                         |
                |  |       "_result" response|
          RTMP  |  |<----------------SFlow-0-|(Str.ID=0,
         Connect|  |                         | Assoc=CFlow-0)
          Hand- |  |"setPeerInfo" command    |
          shake |  |-CFlow-0---------------->|
               -+- |                         |
                   |"createStream" command   |
               -+- |-CFlow-0---------------->|
                |  |                         |
                |  |     "_result" (str.ID=5)|
                |  |<----------------SFlow-0-|
                |  |                         |
                |  |"play" command           |
         (Str.ID=5,|-CFlow-1---------------->|
     Assoc=SFlow-0)|                         |
                |  | StreamBegin User Control|
                |  |<----------------SFlow-1-|(Str.ID=5,
                |  |                         | Assoc=CFlow-0)
                |  |  (RTMP stream events)   |
     Streaming  |  |<----------------SFlow-1-|
                |  |                         |
                |  |        Audio Data       |
                |  |<----------------SFlow-2-|(Str.ID=5,
                |  |                         | Assoc=CFlow-0)
                |  |        Video Data       |
                |  |<----------------SFlow-3-|(Str.ID=5,
                |  |            :            | Assoc=CFlow-0)
                   |            :            |
        

Figure 5: Example NetConnection Message Exchange

图5:NetConnection消息交换示例

5.4. Direct Peer-to-Peer Streams
5.4. 直接对等流

Clients can connect directly to other clients for P2P streaming and data exchange. A client MAY have multiple separate P2P NetStreams with a peer in one RTMFP session, each a separate logical connection. P2P NetStreams are unidirectional, initiated by a subscriber (the side issuing the "play" command) to a publisher. The subscribing peer has a control flow to the publisher. The publisher has zero or more return flows to the subscriber associated to the subscriber's control flow, for the stream media and data.

客户端可以直接连接到其他客户端进行P2P流媒体传输和数据交换。一个客户端可能有多个单独的P2P网络流,在一个RTMFP会话中有一个对等方,每个对等方都有一个单独的逻辑连接。P2P网络流是单向的,由订阅者(发出“播放”命令的一方)向发布者发起。订阅对等方具有到发布服务器的控制流。对于流媒体和数据,发布服务器具有零个或多个到订阅服务器的返回流,这些返回流与订阅服务器的控制流关联。

5.4.1. Connecting
5.4.1. 连接

A client desires to subscribe directly to a stream being published in P2P mode by a publishing peer. The client learns the peer ID of the publisher and the stream name through application-specific means.

客户端希望直接订阅由发布对等方以P2P模式发布的流。客户端通过特定于应用程序的方式学习发布服务器的对等ID和流名称。

If the client does not already have an RTMFP session with that peer ID, it initiates a new session, creating an EPD containing a Fingerprint option (Section 4.4.2.3) for the publisher's peer ID and using the server session's DESTADDR as the initial candidate address for the session to the peer. The server acts as an Introducer (Section 3.5.1.6 of RFC 7016), using forward and redirect messages to help the client and the peer establish a session.

如果客户端尚未具有具有该对等ID的RTMFP会话,则会启动一个新会话,为发布者的对等ID创建一个包含指纹选项(第4.4.2.3节)的EPD,并使用服务器会话的DESTADDR作为对等会话的初始候选地址。服务器充当介绍人(RFC 7016第3.5.1.6节),使用转发和重定向消息帮助客户端和对等方建立会话。

When an S_OPEN session exists to the desired peer, the client creates a new independent flow to that peer. The flow MUST have a non-zero Stream ID. The client sends an RTMP "play" command over the flow, giving the name of the desired stream at the publisher. This flow is the subscriber's control flow.

当所需对等方存在S_OPEN会话时,客户端将创建一个新的独立流到该对等方。流必须具有非零流ID。客户端通过流发送RTMP“play”命令,在发布服务器上给出所需流的名称。此流是订阅者的控制流。

5.4.2. Return Flows for Stream
5.4.2. 流的返回流

The publisher, on accepting a new flow not indicating a return association with any of its sending flows and having a non-zero Stream ID, receives and processes the "play" command. If and when the request is acceptable to the publisher, it opens one or more return flows to the subscribing peer, associated to the subscriber's control flow and having the same Stream ID. The publisher sends a StreamBegin User Control message, appropriate RTMP status events, and the stream media over the one or more return flows.

发布者在接受一个新流时,如果该新流不指示与它的任何发送流的返回关联,并且具有非零流ID,则接收并处理“play”命令。如果发布服务器可接受该请求,则会向订阅对等方打开一个或多个返回流,该返回流与订阅服务器的控制流关联并具有相同的流ID。发布服务器通过一个或多个返回流发送StreamBegin用户控制消息、适当的RTMP状态事件和流媒体。

The subscriber uses the return association of the media flows to the subscriber control flow to determine the stream to which the media belongs.

订户使用媒体流到订户控制流的返回关联来确定媒体所属的流。

The publisher MAY open any number of media flows for the stream and close them at any time. The opening and closing of media flows has no semantic meaning for the stream, except that the opening of at least one flow and the reception of at least one media message or a StreamBegin User Control message indicates that the publisher is publishing the requested stream to the subscriber.

发布者可以为流打开任意数量的媒体流,并随时关闭它们。媒体流的打开和关闭对于流没有语义意义,除了至少一个流的打开和至少一个媒体消息或StreamBegin用户控制消息的接收指示发布者正在向订阅者发布所请求的流之外。

         Subscriber                                     Publisher
         ------>--Subscriber-Control-Flow------------------>--+
                                                              |
               <------------------Publisher-Stream-Flow-1--<--+
                                              :               |
               <------------------Publisher-Stream-Flow-N--<--+
        
         Subscriber                                     Publisher
         ------>--Subscriber-Control-Flow------------------>--+
                                                              |
               <------------------Publisher-Stream-Flow-1--<--+
                                              :               |
               <------------------Publisher-Stream-Flow-N--<--+
        

Figure 6: Schematic Flow Association Tree for a P2P Direct Connection

图6:P2P直接连接的流程关联树示意图

5.4.3. Closing the Connection
5.4.3. 关闭连接

Either end can close the stream by closing or rejecting the subscriber's control flow. The publisher SHOULD close and unpublish to the subscriber on receipt of a close/complete of the control flow. The subscriber SHOULD consider the stream closed on notification of any exception on the control flow.

任何一端都可以通过关闭或拒绝订阅者的控制流来关闭流。发布者应在收到控制流的关闭/完成后关闭并取消发布给订阅服务器。订阅服务器应该考虑在控制流上的任何异常通知时关闭的流。

6. IANA Considerations
6. IANA考虑

This memo specifies option type code values for Certificate fields (Section 4.3.3), Endpoint Discriminator fields (Section 4.4.2), and Session Keying Component fields (Section 4.5.2). It also specifies a flow metadata signature (Section 5.1.1). The type code values and signatures for this profile are assigned and maintained by Adobe, and therefore require no action from IANA.

本备忘录规定了证书字段(第4.3.3节)、端点鉴别器字段(第4.4.2节)和会话键控组件字段(第4.5.2节)的选项类型代码值。它还指定了流元数据签名(第5.1.1节)。此配置文件的类型代码值和签名由Adobe分配和维护,因此不需要IANA执行任何操作。

6.1. RTMFP URI Scheme Registration
6.1. RTMFP URI方案注册

This memo describes use of an RTMFP URI scheme (Section 4.4.2.2, Section 5.3.1, Figure 5). Per this section, the "rtmfp" URI scheme has been registered by IANA.

本备忘录描述了RTMFP URI方案的使用(第4.4.2.2节,第5.3.1节,图5)。根据本节,“rtmfp”URI方案已由IANA注册。

The syntax and semantics of this URI scheme are described using the Augmented Backus-Naur Form (ABNF) [RFC5234] rules from RFC 3986.

这个URI方案的语法和语义是使用RFC3986中的增广的Backus Naur Form(ABNF)[RFC5234]规则描述的。

URI scheme name: rtmfp

URI方案名称:rtmfp

Status: provisional

现状:临时

URI scheme syntax:

URI方案语法:

      rtmfp-uri-scheme = "rtmfp:"
                       / "rtmfp://" host [ ":" port ] path-abempty
        
      rtmfp-uri-scheme = "rtmfp:"
                       / "rtmfp://" host [ ":" port ] path-abempty
        

URI scheme semantics: The first form is used in the APIs of some implementations to indicate instantiation of an RTMFP client according to this memo, but without connecting to a server. Such an instantiation might be used for pure peer-to-peer communication.

URI模式语义:第一种形式在一些实现的API中使用,用于根据此备忘录指示RTMFP客户机的实例化,但不连接到服务器。这种实例化可以用于纯对等通信。

The second form provides location information for the server to which to connect and optional additional information to pass to the server. The only operation for this URI form is to connect to a server (initial candidate address(es) for which are named by host and port) according to Section 5.3. The UDP port for initial candidate addresses, if not specified, is 1935. If the host is a reg-name, the initial candidate address set SHOULD comprise all IPv4 and IPv6 addresses to which reg-name resolves. The semantics of path-abempty are specific to the server. Connections are made using RTMFP as specified by this memo.

第二个表单提供要连接到的服务器的位置信息以及要传递到服务器的可选附加信息。此URI表单的唯一操作是根据第5.3节连接到服务器(初始候选地址由主机和端口命名)。初始候选地址的UDP端口(如果未指定)为1935。如果主机是注册名称,则初始候选地址集应包括注册名称解析到的所有IPv4和IPv6地址。路径abempty的语义特定于服务器。按照本备忘录的规定,使用RTMFP进行连接。

Encoding considerations: The path-abempty component represents textual data consisting of characters from the Universal Character Set. This component SHOULD be encoded according to Section 2.5 of RFC 3986.

编码注意事项:path abempty组件表示由通用字符集的字符组成的文本数据。该组件应根据RFC 3986第2.5节进行编码。

Applications/protocols that use this URI scheme name: The Flash runtime (including Flash Player) from Adobe Systems Incorporated, communication servers such as Adobe Media Server, and interoperable clients and servers provided by other parties, using RTMFP according to this memo.

使用此URI方案名称的应用程序/协议:根据本备忘录,使用RTMFP的Adobe Systems Incorporated的Flash运行时(包括Flash Player)、通信服务器(如Adobe Media Server)以及其他方提供的可互操作客户端和服务器。

Interoperability considerations: This scheme requires use of RTMFP as defined by RFC 7016 in the manner described by this memo.

互操作性注意事项:该方案要求按照本备忘录所述的方式使用RFC 7016定义的RTMFP。

Security considerations: See Security Considerations (Section 7) in this memo.

安全注意事项:参见本备忘录中的安全注意事项(第7节)。

Contact: Michael Thornburgh, Adobe Systems Incorporated, <mthornbu@adobe.com>.

联系人:Michael Thornburgh,Adobe系统公司<mthornbu@adobe.com>.

Author/Change controller: Michael Thornburgh, Adobe Systems Incorporated, <mthornbu@adobe.com>.

作者/变更控制人:迈克尔·桑伯格,Adobe系统公司<mthornbu@adobe.com>.

References: Thornburgh, M., "Adobe's Secure Real-Time Media Flow Protocol", RFC 7016, November 2013.

参考文献:Thornburgh,M.,“Adobe的安全实时媒体流协议”,RFC 7016,2013年11月。

This memo.

这份备忘录。

7. Security Considerations
7. 安全考虑

Section 4 details the cryptographic aspects of this profile.

第4节详细介绍了此概要文件的加密方面。

This profile does not define or use a Public Key Infrastructure (PKI). Clients SHOULD use static Diffie-Hellman keys in their certificates (Section 4.3.3.5). Clients MUST create a new certificate with a distinct fingerprint for each new NetConnection (Section 5.3). These constraints make client identities ephemeral but unable to be forged. A man-in-the-middle cannot successfully interpose itself in a connection to a target client addressed by its fingerprint/peer ID if the target client uses a static Diffie-Hellman public key.

此配置文件未定义或使用公钥基础结构(PKI)。客户端应在其证书中使用静态Diffie-Hellman密钥(第4.3.3.5节)。客户端必须为每个新网络连接创建一个具有不同指纹的新证书(第5.3节)。这些约束使客户端身份短暂但无法伪造。如果目标客户机使用静态Diffie-Hellman公钥,则中间人无法成功插入到由其指纹/对等ID寻址的目标客户机的连接中。

Servers can have long-lived RTMFP instances, so they SHOULD use ephemeral Diffie-Hellman public keys for forward secrecy. This allows server peer IDs to be forged; however, clients do not connect to servers by peer ID, so this is irrelevant.

服务器可以有长寿命的RTMFP实例,因此它们应该使用短暂的Diffie-Hellman公钥来实现前向保密。这允许伪造服务器对等ID;但是,客户端不通过对等ID连接到服务器,因此这与此无关。

When a client connects to a server, the client will accept the response of any endpoint claiming to be "a server". It is assumed that an attacker that can passively observe traffic on a network segment can also inject its own packets with any source or destination and any payload. An attacker can trick a client into connecting to a rogue server or man-in-the-middle, either by observing Initiator Hello packets from the client and responding earliest with a matching Responder Hello or by using tricks such as DNS spoofing or poisoning to direct a client to connect directly to the rogue. A TCP-based transport would be vulnerable to similar attacks. Since there is no PKI, this profile gives no guarantee that the client has actually connected to the desired server, versus a rogue or man-in-the-middle. In circumstances where assurance is required that the connection is directly to the desired server, the client can use the Session Nonces (Section 4.6.5) to challenge the server, for example, over a different channel having acceptable security properties (such as an HTTPS) to transitively establish the server's identity and verify that the end-to-end communication is private and authentic.

当客户端连接到服务器时,客户端将接受声称为“服务器”的任何端点的响应。假设能够被动观察网段上流量的攻击者也可以使用任何源或目标以及任何有效负载注入自己的数据包。攻击者可以通过观察来自客户端的启动器Hello数据包并最早使用匹配的响应程序Hello进行响应,或者通过使用DNS欺骗或中毒等技巧引导客户端直接连接到流氓服务器或中间人,诱使客户端连接到流氓服务器。基于TCP的传输容易受到类似的攻击。由于没有PKI,与流氓或中间人相比,此配置文件无法保证客户端已实际连接到所需的服务器。在需要保证直接连接到所需服务器的情况下,客户端可以使用会话nonce(第4.6.5节)来质询服务器,例如,通过具有可接受安全属性(如HTTPS)的不同通道以过渡方式建立服务器的身份,并验证端到端通信是私有的和真实的。

When session sequence numbers (Section 4.7.3.3) are not used, it is possible for an attacker to use traffic analysis techniques and record encrypted packets containing the start of a new flow, and

当未使用会话序列号(第4.7.3.3节)时,攻击者可能使用流量分析技术并记录包含新流开始的加密数据包,以及

later to replay those packets after the flow has closed, which can look to the receiver like a brand new flow. In circumstances where this can be detrimental, session sequence numbers SHOULD be used. Replay of packets for existing flows is not detrimental as the receiver detects and discards duplicate flow sequence numbers, and flow sequence numbers do not wrap or otherwise repeat.

稍后在流关闭后重播这些数据包,这对接收者来说就像是一个全新的流。在可能有害的情况下,应使用会话序列号。对现有流重放数据包不会造成损害,因为接收器检测并丢弃重复的流序列号,并且流序列号不会包装或以其他方式重复。

Packet encryption uses CBC with the same (null) initialization vector for each packet. This can reveal to an observer whether two packets contain identical plaintext. However, the maximum-length RTMFP common header and User Data or Data Acknowledgement header, including flow sequence number, always fit within the first 16-byte cipher block, so each initial cipher block for most packets will already be unique even if timestamps are suppressed. Sending identical messages in a flow uses unique flow sequence numbers, so cipher blocks will be unique in this case. Keepalive pings and retransmission of lost data can result in identical cipher blocks; however, traffic analysis can also reveal likely keepalives or retransmissions, and retransmission only occurs as a result of observable network loss, so this is usually irrelevant. In circumstances where any identical cipher block is unacceptable, session sequence numbers SHOULD be used as they guarantee each initial cipher block will be unique.

对于每个数据包,数据包加密使用具有相同(空)初始化向量的CBC。这可以向观察者揭示两个数据包是否包含相同的明文。然而,最大长度RTMFP公共报头和用户数据或数据确认报头(包括流序列号)始终适合于前16字节密码块,因此,即使时间戳被抑制,大多数数据包的每个初始密码块也将是唯一的。在流中发送相同的消息使用唯一的流序列号,因此在这种情况下密码块是唯一的。保留ping和重新传输丢失的数据可能导致相同的密码块;然而,流量分析也可以揭示可能的保留或重传,而重传只在可观察到的网络丢失的情况下发生,因此这通常是不相关的。在不能接受任何相同密码块的情况下,应使用会话序列号,因为它们保证每个初始密码块都是唯一的。

Packet verification can use a 16-bit simple checksum (Section 4.7.3.1). The checksum is inside the encrypted packet, so for external packet modifications the checksum is equivalent to a 16-bit cryptographic digest. In circumstances where this is insufficient, HMAC verification (Section 4.7.3.2) SHOULD be used.

数据包验证可使用16位简单校验和(第4.7.3.1节)。校验和在加密数据包内,因此对于外部数据包修改,校验和相当于16位加密摘要。在这还不够的情况下,应使用HMAC验证(第4.7.3.2节)。

8. References
8. 工具书类
8.1. Normative References
8.1. 规范性引用文件

[AES] National Institute of Standards and Technology, "Advanced Encryption Standard (AES)", FIPS PUB 197, November 2001, <http://csrc.nist.gov/publications/fips/fips197/ fips-197.pdf>.

[AES]国家标准与技术研究所,“高级加密标准(AES)”,FIPS PUB 197,2001年11月<http://csrc.nist.gov/publications/fips/fips197/ fips-197.pdf>。

[AMF0] Adobe Systems Incorporated, "Action Message Format -- AMF 0", December 2007, <http://www.adobe.com/go/spec_amf0>.

[AMF0]Adobe Systems Incorporated,“行动消息格式——AMF 0”,2007年12月<http://www.adobe.com/go/spec_amf0>.

[AMF3] Adobe Systems Incorporated, "Action Message Format -- AMF 3", January 2013, <http://www.adobe.com/go/spec_amf3>.

[AMF3]Adobe Systems Incorporated,“行动消息格式——AMF 3”,2013年1月<http://www.adobe.com/go/spec_amf3>.

[CBC] Dworkin, M., "Recommendation for Block Cipher Modes of Operation", NIST Special Publication 800-38A, December 2001, <http://csrc.nist.gov/publications/nistpubs/800-38a/ sp800-38a.pdf>.

[CBC]Dworkin,M.“分组密码操作模式的建议”,NIST特别出版物800-38A,2001年12月<http://csrc.nist.gov/publications/nistpubs/800-38a/ sp800-38a.pdf>。

[DH] Diffie, W. and M. Hellman, "New Directions in Cryptography", IEEE Transactions on Information Theory, V. IT-22, n. 6, June 1977.

[DH]Diffie,W.和M.Hellman,“密码学的新方向”,IEEE信息论交易,V.IT-22,n。1977年6月6日。

[RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, February 1997, <http://www.rfc-editor.org/info/rfc2104>.

[RFC2104]Krawczyk,H.,Bellare,M.,和R.Canetti,“HMAC:用于消息认证的键控哈希”,RFC 2104,1997年2月<http://www.rfc-editor.org/info/rfc2104>.

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997, <http://www.rfc-editor.org/info/rfc2119>.

[RFC2119]Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,1997年3月<http://www.rfc-editor.org/info/rfc2119>.

[RFC3526] Kivinen, T. and M. Kojo, "More Modular Exponential (MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)", RFC 3526, May 2003, <http://www.rfc-editor.org/info/rfc3526>.

[RFC3526]Kivinen,T.和M.Kojo,“因特网密钥交换(IKE)的更模指数(MODP)Diffie-Hellman群”,RFC 3526,2003年5月<http://www.rfc-editor.org/info/rfc3526>.

[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003, <http://www.rfc-editor.org/info/rfc3629>.

[RFC3629]Yergeau,F.,“UTF-8,ISO 10646的转换格式”,STD 63,RFC 3629,2003年11月<http://www.rfc-editor.org/info/rfc3629>.

[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, January 2005, <http://www.rfc-editor.org/info/rfc3986>.

[RFC3986]Berners Lee,T.,Fielding,R.,和L.Masinter,“统一资源标识符(URI):通用语法”,STD 66,RFC 3986,2005年1月<http://www.rfc-editor.org/info/rfc3986>.

[RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008, <http://www.rfc-editor.org/info/rfc5234>.

[RFC5234]Crocker,D.和P.Overell,“语法规范的扩充BNF:ABNF”,STD 68,RFC 5234,2008年1月<http://www.rfc-editor.org/info/rfc5234>.

[RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011, <http://www.rfc-editor.org/info/rfc6234>.

[RFC6234]Eastlake,D.和T.Hansen,“美国安全哈希算法(基于SHA和SHA的HMAC和HKDF)”,RFC 62342011年5月<http://www.rfc-editor.org/info/rfc6234>.

[RFC7016] Thornburgh, M., "Adobe's Secure Real-Time Media Flow Protocol", RFC 7016, November 2013, <http://www.rfc-editor.org/info/rfc7016>.

[RFC7016]Thornburgh,M.,“Adobe的安全实时媒体流协议”,RFC 7016,2013年11月<http://www.rfc-editor.org/info/rfc7016>.

[RFC7296] Kaufman, C., Hoffman, P., Nir, Y., Eronen, P., and T. Kivinen, "Internet Key Exchange Protocol Version 2 (IKEv2)", STD 79, RFC 7296, October 2014, <http://www.rfc-editor.org/info/rfc7296>.

[RFC7296]Kaufman,C.,Hoffman,P.,Nir,Y.,Eronen,P.,和T.Kivinen,“互联网密钥交换协议版本2(IKEv2)”,STD 79,RFC 72962014年10月<http://www.rfc-editor.org/info/rfc7296>.

[RTMP] Adobe Systems Incorporated, "Real-Time Messaging Protocol (RTMP) specification", December 2012, <http://www.adobe.com/go/spec_rtmp>.

[RTMP]Adobe Systems Incorporated,“实时消息传递协议(RTMP)规范”,2012年12月<http://www.adobe.com/go/spec_rtmp>.

[SHA256] National Institute of Standards and Technology, "Secure Hash Standard", FIPS PUB 180-4, March 2012, <http://csrc.nist.gov/publications/fips/fips180-4/ fips-180-4.pdf>.

[SHA256]国家标准与技术研究所,“安全哈希标准”,FIPS PUB 180-42012年3月<http://csrc.nist.gov/publications/fips/fips180-4/ fips-180-4.pdf>。

8.2. Informative References
8.2. 资料性引用

[RFC1035] Mockapetris, P., "Domain names - implementation and specification", STD 13, RFC 1035, November 1987, <http://www.rfc-editor.org/info/rfc1035>.

[RFC1035]Mockapetris,P.,“域名-实现和规范”,STD 13,RFC 10351987年11月<http://www.rfc-editor.org/info/rfc1035>.

[RFC1071] Braden, R., Borman, D., Partridge, C., and W. Plummer, "Computing the Internet checksum", RFC 1071, September 1988, <http://www.rfc-editor.org/info/rfc1071>.

[RFC1071]Braden,R.,Borman,D.,Partridge,C.,和W.Plummer,“计算互联网校验和”,RFC 10711988年9月<http://www.rfc-editor.org/info/rfc1071>.

[RFC4302] Kent, S., "IP Authentication Header", RFC 4302, December 2005, <http://www.rfc-editor.org/info/rfc4302>.

[RFC4302]Kent,S.,“IP认证头”,RFC43022005年12月<http://www.rfc-editor.org/info/rfc4302>.

[RFC4303] Kent, S., "IP Encapsulating Security Payload (ESP)", RFC 4303, December 2005, <http://www.rfc-editor.org/info/rfc4303>.

[RFC4303]Kent,S.,“IP封装安全有效负载(ESP)”,RFC 4303,2005年12月<http://www.rfc-editor.org/info/rfc4303>.

[RFC6479] Zhang, X. and T. Tsou, "IPsec Anti-Replay Algorithm without Bit Shifting", RFC 6479, January 2012, <http://www.rfc-editor.org/info/rfc6479>.

[RFC6479]Zhang,X.和T.Tsou,“不带位移位的IPsec反重放算法”,RFC 6479,2012年1月<http://www.rfc-editor.org/info/rfc6479>.

Acknowledgements

致谢

Special thanks go to Glenn Eguchi, Matthew Kaufman, and Adam Lane for their contributions to the design of this profile.

特别感谢Glenn Eguchi、Matthew Kaufman和Adam Lane为本简介的设计做出的贡献。

Thanks to Philipp Hancke, Kevin Igoe, Paul Kyzivat, and Milos Trboljevac for their detailed reviews of this memo.

感谢Philipp Hancke、Kevin Igoe、Paul Kyzivat和Milos Trboljevac对本备忘录的详细审查。

Author's Address

作者地址

Michael C. Thornburgh Adobe Systems Incorporated 345 Park Avenue San Jose, CA 95110-2704 United States

Michael C.Thornburgh Adobe Systems公司,美国加利福尼亚州圣何塞公园大道345号,邮编95110-2704

   Phone: +1 408 536 6000
   EMail: mthornbu@adobe.com
   URI:   http://www.adobe.com/
        
   Phone: +1 408 536 6000
   EMail: mthornbu@adobe.com
   URI:   http://www.adobe.com/