2.8. 重新生成密钥 (Rekeying)
2.8. 重新生成密钥 (Rekeying)
重新生成密钥是指用一个新的 SA 替换一个已存在的 SA, 而不中断通信的状况。这通常是在旧的 SA 即将到期时完成的。在重新生成密钥期间, 双方必须 (MUST) 就新的密钥材料达成一致。双方必须 (MUST) 能够同时处理来自旧 SA 和新 SA 的数据包。第 2.8 节描述了对子 SA 的重新生成密钥, 而第 2.18 节描述了父 SA (IKE SA) 的重新生成密钥。
虽然重新生成密钥将经常被使用, 但相关的交换并不是强制要求 (REQUIRED) 实现的。具备重新生成密钥功能的实现必须 (MUST) 支持本文档中描述的 CREATE_CHILD_SA 交换。不具备重新生成密钥功能的实现必须 (MUST) 在 IKE_SA_INIT 交换的 SA 载荷中简单地发送一些提议但未包含任何特定于重新生成密钥的属性, 以便对端不会尝试重新生成密钥。不支持重新生成密钥的实现必须 (MUST) 拒绝包含 REKEY_SA 属性的 CREATE_CHILD_SA 交换, 并发送带有 NO_ADDITIONAL_SAS 通知的响应。
当发起方希望重新生成密钥时, 它会发起一个 CREATE_CHILD_SA 交换, 其中包含新 SA 的提议, 并包含指定要被重新生成密钥的 SA 的 REKEY_SA 属性。REKEY_SA 属性中的 SPI 值是要被重新生成密钥的 SA 在出方向上使用的 SPI。也可以使用具有 REKEY_SA 属性的 SA 载荷来重新生成密钥一个被删除的 SA, 在这种情况下, SPI 值是被删除的 SA 的出方向 SPI。在 CREATE_CHILD_SA 交换中, 旧的 [淡出] SA 仍在使用 (即, 旧的 SA 未从 SA 数据库 (SAD) 中删除, 直到重新生成密钥交换完成), 并且新的 [淡入] SA 得到了建立。发起方将使用刚建立的 SA 作为新 SA, 并将旧的 SA 标记为 "死的" (即, 尽快删除)。响应方将旧的 SA 标记为 "活的", 但使用新建立的 SA 作为新 SA。换言之, 双方都从使用旧的 SA 切换到使用新的 SA, 但是响应方在能这样做之前必须 (MUST) 等待确认。
当前 SA 的持有者 (即, 在 IKE_SA_INIT 交换中发送 SA 提议的一方) 必须 (MUST) 在重新生成密钥交换中作为发起方, 因为新的 SA 必须 (MUST) 由持有者进行提议。这避免了同时重新生成密钥交换的死锁。要使一个 SA 重新生成密钥, 必须 (MUST) 由 SA 的持有者发起 CREATE_CHILD_SA 交换。
在实现接受即将使用的 SA 之前, 它可能要等待确认旧的 SA 已经从对端的 SAD 中删除。在这种情况下, 实现必须 (MUST) 等待 INFORMATIONAL 交换中的删除通知 (见第 2.4 和 3.11 节)。在收到这样的删除通知之前, 实现必须 (MUST) 保留旧的 SA, 因为对端可能仍然在使用它。这个等待既是发起方也是响应方的责任。实现不应该 (SHOULD NOT) 无限期地保留旧的 SA, 但它们必须 (MUST) 保留旧的 SA 直到删除通知到达, 或者直到 SA 的生存时间 (由该 SA 的协商生存时间确定) 到期。
如果具备重新生成密钥功能的实现在 IKE_SA_INIT 交换期间收到一个带有 REKEY_SA 属性的提议, 它必须 (MUST) 以一个带有 NO_ADDITIONAL_SAS 通知的响应来拒绝该提议。如果实现不支持重新生成密钥, 它必须 (MUST) 拒绝包含 REKEY_SA 属性的 CREATE_CHILD_SA 交换, 并发送带有 NO_ADDITIONAL_SAS 通知的响应。在 IKE_SA_INIT 交换中接收到的包含 REKEY_SA 属性的提议是一个错误; 然而, 在 CREATE_CHILD_SA 交换中接收到的包含 REKEY_SA 属性的提议是有效的。
如果重新生成密钥交换失败 (例如, 因为 NO_ADDITIONAL_SAS 或是因为出现了无效的提议), 旧的 SA 仍然可用, 并且可以 (MAY) 在以后尝试重新生成密钥。如果旧的 SA 到期, 通信中断, 并且如果双方的策略允许, 可以 (MAY) 建立一个新的 SA (可能是一个全新的 IKE SA)。
资源耗尽是一种拒绝服务攻击, 其中攻击者通过请求过多的 SA 来消耗受害者的资源。为了避免这种攻击, 实现应该 (SHOULD) 限制在任何给定时间被重新生成密钥的 SA 数量, 以及由单个 IKE SA 建立的子 SA 数量。
2.8.1. 同时重新生成密钥
同时重新生成密钥是指两个对端都发起了重新生成密钥交换的情况。为了避免两个独立的 CREATE_CHILD_SA 交换同时发生时的死锁, 并为了避免可能出现的两个新 SA 协商不一致的 ID 的问题, 实现必须 (MUST) 遵循以下规则:
-
原始的 SA 持有者必须 (MUST) 继续作为新的 CREATE_CHILD_SA 交换的发起方。
-
如果响应方收到了一个 CREATE_CHILD_SA 交换, 该交换试图重新生成密钥一个它已经发出了重新生成密钥请求的 SA, 那么响应方必须 (MUST) 允许对端的重新生成密钥请求优先于它自己的。在这种情况下, 响应方应该 (SHOULD) 删除它自己发起的 SA, 并使用由对端创建的 SA。响应方必须 (MUST) 将新的 SPI 发送给发起方, 以便发起方知道使用哪个 SPI。
-
在任何给定的时间, 不应该 (SHOULD NOT) 有多于两个与同一原始 SA 相关且处于活动状态的 SA。
为了避免同时重新生成密钥, 实现可以 (MAY) 在它开始重新生成密钥交换之前等待一个随机的时间量。如果它收到了一个由对端发起的重新生成密钥请求, 而它自己还没有发起重新生成密钥, 那么它应该 (SHOULD) 允许对端的请求优先于它自己的。