IKEV1 IPSec协商过程
前情提要:(无广)本人网络报班于太阁,安全报班于乾颐堂(被乾颐堂的名声所骗),在看了两家关于ipsec的视频以及秦科撰写的《ciscoipsecvpn实战指南》之后,仍觉得一知半解,可能这也是国内应试教育风气所产生的结果,故在翻阅了各方文档以及咨询了安全业界高级工程师之后补全了我个人所需的关于ipsec的理论,分享于该博客。
IPSec分为两个阶段,一阶段分为主模式(main mode)和野蛮模式(aggressive mode),二阶段称为快速模式(quick mode),本文只讨论一阶段为主模式的情况。
在讲IPSec之前,我想先说明一下一个比较关键的技术:
DH(Diffie-Hellman)

DH有很多版本,Group x,这个称为DH的组号,组号越大代表DH算法形成的密钥长度越长,长度越长越安全,这里的密钥长度会被带入协商计算,俗称为p
A---B
双方先交互一个素数,俗称为g,彼此都随机生成一个私钥,并用私钥计算出公钥,把公钥发送给对方,对方能用接受到的公钥计算出相对应的共享密钥,计算方式如下:
A生成一个私钥a,用于计算公钥X=g^a mod p,并发给B
B生成一个私钥b,用于计算公钥Y=g^b mod p,并发给A
彼此收到之后,接下来计算共享密钥:
A计算Z=Y^a mod p,B计算Z=X^b mod p
由于数学性质 (g^b mod p)^a mod p = (g^a mod p)^b mod p,双方会得到一个相同的 Z
计算得出的Z会用于后续密钥计算
阶段一(产生一条双向的SA,1-4包以明文的形式交互):
Initiator --Internet-- Responder
第一个包:
Initiator产生一个Cookie:HASH(ip+端口+协议+日期+随机数),把这个cookie放入IKE头部,也就是IKE头部中的initiator cookie,此时因为是首发报文,responder cookie置0,该cookie用于告知对面应该使用哪个密钥来加密,并用于后续DH算法计算密钥
并且产生一个或多个IKE SA提案,取决于本地配置了多少个,主要有5类参数:
加密算法
哈希算法
身份认证算法:PSK/SIG
DH组
Lifetime(默认为86400s)
注:此处PSK仅仅只是PSK方式,而不是指PSK密钥
Initiator会把IKE头部和IKE SA提案一并发送给Responder
第二个包:
Responder收到报文之后,查看SA提案,读取其中的参数并与本地配置做对比查看是否支持,如果本地有相对应的组合,则会在ISAKMP SA RESPONSE里面携带这个组合的内容
如果不匹配,就会发送Notification报文告诉对方:协商失败。匹配之后,在IKE头部中填入自己产生的Cookie,把IKE头部与SA提案一并发送给Initiator。此时双方都有了彼此的cookie值
发起者的SA载荷能够有多种算法提案,但是响应者的SA协商载荷一定只有一种提案
第三个包:
Initiator → Responder。发送IKE头部、X、Ni
X就是DH计算得出的公钥,Ni是随机数,是当前时间戳的哈希值
第四个包:
Responder → Initiator。响应IKE头部、Y、Nr
Y是响应者计算得出的公钥,以及Nr是响应者当前时间戳的哈希值
交互完成后,双方计算出Z,用Z进一步计算SKEYID,用于后续身份认证和密钥派生:
SKEYID = prf(Ni | Nr, Z)
prf:伪随机函数(通常是 HMAC-SHA1 或其他哈希算法)
Z:DH 计算出的共享密钥
SKEYID计算完成之后,IKEV1用prf进一步派生3把密钥:
SKEYID_d = prf(SKEYID, gxy | CKY-I | CKY-R)
用于派生 IPSec SA 的密钥材料(如 ESP/AH 的加密和完整性密钥)SKEYID_a = prf(SKEYID, SKEYID_d | gxy | CKY-I | CKY-R)
用于 IKE 报文的身份认证,确保数据完整性和防篡改。SKEYID_e = prf(SKEYID, SKEYID_a | gxy | CKY-I | CKY-R)
用于 IKE 报文的机密性保护(加密 IKE 报文)。
gxy:即Z(DH共享密钥)
CKY-I:发起者的Cookie
CKY-R:响应者的Cookie
prf(SKEYID,…)代表HMAC计算,输入SKEYID作为密钥,对后面的数据计算HMAC以得到密钥值
举例:
身份认证:IKE消息中的AUTH字段会用SKEYID_a计算HMAC-SHA1以验证完整性
加密:如果IKE选择了AES-CBC作为加密算法,则SKEYID_e作为密钥加密后续IKE消息
第二对报文交互好,安全隧道就已经形成了。接下来交互第三对报文,就是做身份验证。
第五个包:
发起者载荷:
HDR, IDi, HASH_IIDi:发起者的身份标识(Local ID),可能是 IP 地址、FQDN、EMAIL 等
HASH_I:由 SKEYID、ID、Nonce、DH 共享密钥 Z 计算得出的认证哈希值,用于身份验证
注:此时第五个包开始已经处于加密阶段,使用IKE SA
第六个包:
响应者载荷:
HDR, IDr, HASH_R阶段一主模式协商交互6个报文(一般用于LAN-2-LAN)
阶段二(也称为Quick Mode,两条单向SA,密文交互):
阶段二主要用于协商IPSEC SA,并派生用于ESP/AH加密和完整性的密钥。如果启用PFS,还需要进行新的DH计算,否则IPSEC SA密钥会直接从IKE阶段1派生。
Quick Mode基于3个消息的交互,通常封装在加密的IKE隧道内,使用SKEYID_e进行加密:
Initiator(发起者)发送Quick Mode提议
Responder(响应者)接受提议并返回选择的参数
Initiator确认SA帮完成密钥交换
第一个包:
发起者发送Quick Mode提议,包括:SPI、加密算法、完整性算法、密钥生存期(Lifetime)、身份验证数据(HMAC校验)、Nonce(随机数Ni)、新的DH公钥(如果开启PFS)
Msg1: { SPI-I, Proposed SA (ESP/AH), Encryption, Integrity, Lifetime, Ni, DH Public Key Xi }_SKEYID_eSPI-I:发起者的 IPSec SPI
Proposed SA:发起者支持的 SA 参数(ESP/AH、加密算法、HMAC 方案)
Xi:发起者的 DH 公钥(仅在 PFS 模式下)
整个消息用 SKEYID_e 加密
第二个包:
响应者解析加密的消息,检查提案,并返回选定的参数:
Msg2: { SPI-R, Accepted SA, Encryption, Integrity, Lifetime, Nr, DH Public Key Xr }_SKEYID_ePFS情况下:
计算新的 DH 共享密钥 Z' = (Xi^b mod p) = (Xr^a mod p)
之后 IPSec SA 的密钥 由 Z' 计算,而不是 SKEYID_d
第三个包:
第一步:发起者先解析响应者的消息,然后计算最终密钥(KEYMAT)
如果未启用PFS:
KEYMAT = prf(SKEYID_d, Protocol | SPI-I | SPI-R | Ni | Nr)如果启用PFS:
KEYMAT = prf(Z', Protocol | SPI-I | SPI-R | Ni | Nr)Z' 是 Quick Mode 期间计算的新 DH 共享密钥
Protocol 表示 ESP 或 AH
第二步:生成IPSEC SA(由KEYMAT拆分所得)
KEYMAT = EncKey | AuthKeyEncKey→ESP/AH的加密密钥
AuthKey→ESP/AH的完整性密钥
第三步:发送SA确认
Msg3: { HASH }_SKEYID_eHASH = prf(SKEYID_a, Msg1 | Msg2 | Msg3)
用于校验双方SA的协商结果
依旧用SKEYID_e加密
ESP(封装安全载荷)
Ethernet2 | IPv4 | ESP | TCP | HTTP | FCS
做了ESP就只能查看IPv4报头了,就看不到TCP UDP报头了(加密处理),所以做了PAT的设备就不行。为了让NAT设备通信,所以要用NAT-T也就是NAT穿越技术,做了这个技术就会在ESP报头前面再添加一个UDP报头,通过这个UDP报头,提供原目端口实现转换
Ethernet2 | IPv4 | UDP | ESP | TCP | HTTP | FCS
