0

我有使用 Web 套接字来传输数据的服务。

我需要一种方法来编码树结构并通过 websocket 传输该树结构。我一直在阅读有关 TLV 和 sub-TLV 编码的内容,这似乎是一个好主意,即它已经在诸如 Radius、LLDP 等协议中使用,这证明这是有效的,但是我的问题是这些协议通常在一个受信任的设备,即交换机/路由器之间(LLDP 除外)。我的问题是,我将传输包含子 TLV 的 TLV,这些子 TLV 确实具有随机大小/长度,并且它们没有静态定义的结构,例如,如果您查看第一个 TLV 中的概念已定义子 TLV,即

Extended IS Reachability TLV #22 然后你会看到这个 tlv 有这样的结构:

  /* +-------+-------+-------+-------+-------+-------+-------+-------+
   * |                        Type                                   | 1
   * +---------------------------------------------------------------+
   * |                        Length ID                              | 1
   * +---------------------------------------------------------------+
   * |                        Neighbour ID                           | 7
   * +---------------------------------------------------------------+
   * |                        TE Metric                              | 3
   * +---------------------------------------------------------------+
   * |                        SubTLVs Length                         | 1
   * +---------------------------------------------------------------+
   * |                        SubTLVs value                          | variable
   * +---------------------------------------------------------------+
   * :                                                               :
   */

通过结构,我的意思是我已经预定义了 7 个字节的邻居 ID、3 个字节的 Metric、1 个字节的 SubTLVs 长度,然后才出现可变部分,但至少你有一些预先定义的位并且不能更改。

现在通过阅读一些书籍(主要是 H Gredler The Complete IS-IS Routing Protocol 2005 - 第 296 页),我发现了 4 种验证这些 TLV 的技术,即

1) 最大长度检查

2) Sub-TLV 溢出检查

3) 离散长度检查

4) TLV 内容模式检查

我根本无法相信用户的意见,但我还有两个问题,即如何验证值为 a) 随机长度/大小的 TLV,即我确实有一个值可能具有的范围,即不小于 1 字节不大于 700 kb 和 b) 我不能对该值执行任何模式检查,因为它是加密的,即不可读形式,因此不能对其执行任何模式。

因此我的问题是:如何实现相同的目标,即在其他结构中发送树结构,即可能是键值对或类似的东西(http 正在使用这个,应该有原因)。

TLV 方式真的是在树结构中传输数据的最佳选择吗?我知道,如果我以二进制形式发送它,我将一枪击中两只兔子,即在发送图片等文件时,我不需要使用一些有趣的 base64 编码等,但我真正想要的是一个适用的协议L5-7(即通过 websocket)将允许以树结构的形式发送数据,接收部分将能够识别和重新组装树,而无需考虑序列化和反序列化部分。那么 TLV 的第二个最佳替代方案是什么?考虑到我一方面使用 java,另一方面使用 javasctipt。

4

1 回答 1

0

这是对评论中问题的回答,而不是原始问题。

有许多选项可让您检查协议错误:

  1. 由于您type使用的是 while 字节(并且您可能没有 256 种不同的类型),您可以检查它type是否有效。如果不是,则存在协议错误。

  2. 您可以在可变长度value字段之后添加一个两字节字段,其中包含该字段的第一个和最后一个字节value。如果这些不匹配,则存在协议错误;或者

  3. 您可以在 之后添加一个固定大小的 MD5 哈希字段value,并根据哈希值检查值的内容。如果数据无效,则存在协议错误(或中间人攻击)。

使用哈希(校验和),如选项 3(我建议使用 MD-5,但任何校验和方法都可能很棒)是检查数据完整性和协议一致性的好方法。

使用第一个和最后一个字节审查(选项 2)只会检查协议一致性,而不是数据完整性。

验证type字段(选项 1)是检查协议完整性的一种简单方法,但容易出错(因为随机数据更可能看起来有效)。

根据实际数据的长度(问题中的选项 1-3)检查接收到的数据的长度很容易出错,并且很可能会导致错误。这是因为多余的数据可能被认为是下一个“帧”的一部分,因此只有当数据丢失并且没有接收到更多数据时才会显示错误。

编辑:有关选项 2 与 3 的更多详细信息

当使用第一个和最后一个字节验证时,每帧随机数据应该有大约 1:65,536 的机会通过此验证测试(这对于非关键单帧数据来说可能是一个足够好的测试)。

此外,如果您的数据树包含许多“数据字段”值,则该数字增长得非常快。(当提供随机数据时,一个 4 数据字段树只有 1:2^64 的有效性机会。

IE

假设数据长度为 1 个字节,字节值为 10(十六进制中的 0A)。

第一个字节和最后一个字节都等于 0A,这意味着验证字段必须是 0A0A 的双字节值。这是 2^16 个选项中唯一可接受的值。

但是,它不承诺数据完整性。

假设客户端使用evilproxy.com服务连接到我们的服务器......

如果该值是值为 100001 的银行帐号,evilproxy.com可以将帐号更改为任何值,只要第一个和最后一个数字相同(即 199991),允许evilproxy.com在协议的消息仍然保留的同时更改数据有效的。

另一方面,使用校验和(如 MD5 静默)意味着在本例中操作帐号时校验和的值会发生变化。

MD5 使用 128 位(16 字节),这意味着随机验证字段值有 1:2^128 的机会“达到目标”(这是一个可以忽略不计的机会)。

另一方面,如果evilproxy.com知道您用于校验和的算法的“盐”,则该字段可以与数据一起更新。

因此,如果您希望传达更敏感的数据,最好考虑使用校验和。

于 2015-12-17T03:11:50.137 回答