当通信双方建立了一个SA后,它们就有了所有用来计算它们交换的数据报的ICV值的参数。ICV的计算涉及到整个IP头,然而有些域在从源到目的的传输过程中可能会改变,所以在计算ICV时将这些域设为0。首先需要了解IPv4和IPv6数据包头的可变域和不变域。哪些被计算进去了,而哪些被设置为0.
(图片来源于搜索)
服务类型(Type of service):8比特的服务类型(TOS)域表明了数据报所属数据流的需求,这个需求是针对延迟、吞吐量和可靠性的组合而言的。IP协议并不认为这个域是可变的,但IPSec将它作为可变域对待,因为现有的一些路由器会改变这些域。
标志(FLAGS):IP头中有三个标志位。第一个是DF(不可分段)位,当这个位被设置的时候表明不允许对数据报分段。第二个是MF(更多分段)位,当这个位为0的时候表明数据包的最后一个数据分段到达。第三个被保留做将来使用。ICV的计算不包括这个域,因为即使数据源没有设置这个位,中间的路由器也可能设置DF位。
分段偏移量(Fragment offset):这个13比特的域表明一个分段在它所属的数据报中的位置。AH仅应用于非分段的IP包;所以在计算ICV之前,必须将这个域设为0。
TTL:这8比特的域被用来限制一个数据报的生命期,因此可以防止数据报在一个网段中无限循环。数据报在经过每个路由器时,它的TTL值都被路由器减小。目的主机无法预计TTL值,所以这个域被排除在ICV的计算之外。
头校验值(Header checksum):这个16比特域保存IP头的校验和。如果IP头的任一个域发生了变化,校验和的值也会变化,所以在计算ICV之前,必须将这个域设为0。
可选项(Options):这个变长域存放数据包的可选信息,比如安全性和处理限制。这个域很少被使用,并且被大多数的路由器忽略。所以大部分的IPSec实现在计算ICV时都不包含可选项。
逐跳和目的选项扩展头中包含一个比特,用来表明这个选项在传输过程中是否可能发生变化。可以通过设置和取消这些比特来指定这些扩展头可变还是不可变。逐跳扩展头被用来携带可选的路由信息,数据报从源到目的沿途的每个节点都必须检查这些信息。目的选项扩展头携带仅需由目的节###IPv6头的不变域
路由扩展头有可变但可预测的特性。IPv6数据源用这个扩展头列出数据包从源到目的途径中的一个或多个网关。路由扩展头中的地址域可能在传输中被重排;然而数据包在目的主机时的内容的形式对发送者和中间节点而言却是已知的。所以,可以由发送者排列地址域使其和发送到目的地时相同。因此是在计算ICV时包含了这个扩展头。如果有分段扩展头的话,它对IPSec而言是不可见的,因为它在外出的IPSec处理后才出现;而重组工作在进入IPSec处理之前进行。所以,在计算ICV时这个扩展头不予考虑。
把IP的可变域和IPv6可变扩展头设为0后,整个IP数据报以一个比特串的形式作为MAC的输入。MAC采用指定的密钥生成ICV。值得注意的是,在隧道模式中,内部IP头的可变域未被设为0,因为只有外部IP头的可变域才可能在传输过程中被修改。
ICV的长度依赖于使用的MAC算法。例如,对于HMAC-MD5,ICV是128比特;而对于HMAC-SHA1,ICV是160比特。如果一个MAC算法生成的IPv4数据报的ICV长度不是32的整数倍,或生成的IPv6数据报的ICV长度不是64的整数倍,则需要增加填充比特使ICV达到32(IPv4)或64(IPv6)的整数倍。计算出ICV(有必要的话还得对它进行填充)之后,把它放在认证数据域中,然后数据报将被发送到目的地址。