IPSec ESP载荷解密后IPv4头部异常,如何修正OpenSSL命令?
问题
我正在开发一款实现IPSec功能的应用,该应用接收加密数据包,解密后转发至其他应用。目前用Scapy发送AES-CBC-128模式加密的ESP数据包,应用接收后需要解密ESP载荷(其他头部已处理)。
相关数据
- 加密ESP载荷(十六进制):
df 2d 42 15 29 ca 6c 77 9d 60 03 ef 4f 1d fa a9 44 85 39 80 b3 e1 9d d1 e9 21 ec e2 7c 9c 8c 23 14 40 6d 52 f9 40 f5 65 81 67 99 60 0c cd e2 e8 - 解密后数据(十六进制):
af d4 00 50 00 00 00 00 00 00 00 00 50 02 20 00 87 df 00 00 48 65 6c 6c 6f 20 57 6f 72 6c 64 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 0f 06- 前20字节为无效IPv4头部,无法构建IP包;
48 65 6c 6c 6f 20 57 6f 72 6c 64对应明文Hello World;01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 0f 06为填充数据。
当前使用命令
echo <encrypted-esp-payload> | xxd -r -p | openssl aes-128-cbc -d -K <key> -iv <iv> -nopad | xxd -p
需求
解密后得到正确的IPv4头部值,用于构建数据包。
环境信息
- OpenSSL版本:3.0.2
- IV和密钥长度均为16字节
- 用xxd处理十六进制转储
Scapy发送命令
sa = SecurityAssociation(ESP, spi=<spi>, crypt_algo='AES-CBC', crypt_key=b'<crypt_key>') p = IP(src='1.1.1.1', dst='2.2.2.2')/TCP(sport=45012, dport=80)/Raw('Hello World') p = IP(raw(p)) e = sa.encrypt(p, iv=b'<iv>') sendp(Ether(src='00:11:22:33:44:55', dst='00:00:00:00:00:05')/e, iface="veth0")
捕获的数据包数据
11:34:15.121850 IP 1.1.1.1 > 2.2.2.2: ESP(spi=0xdeadbeef,seq=0x1), length 72 0x0000: 4500 005c 0001 0000 4032 746a 0101 0101 E..\....@2tj.... 0x0010: 0202 0202 dead beef 0000 0001 6669 7865 ............fixe 0x0020: 645f 6976 5f31 3662 7974 6573 df2d 4215 d_iv_16bytes.-B. 0x0030: 29ca 6c77 9d60 03ef 4f1d faa9 57cf 6e29 ).lw.`..O...W.n) 0x0040: f0ad e7f8 668f 6c66 29a3 c4fe bc3c 57eb ....f.lf)....<W. 0x0050: 2f27 f997 9f81 59ac 2cf7 277b /'....Y.,.'{
解决方案
问题根源
-nopad参数误用:ESP的填充符合PKCS#7规范,-nopad会阻止OpenSSL自动移除填充数据及后续的填充长度、下一个头部字段,导致解密结果混入无效数据。- IV不匹配:从捕获数据包看,ESP载荷前16字节是固定IV(对应字符串
fixed_iv_16bytes,十六进制为66697865645f69765f31366279746573),你手动指定的IV与实际传输的IV不一致,导致解密出乱码的IP头部。
调整后的命令
移除-nopad参数,并使用数据包中实际的IV:
# 替换<your-key-hex>为16字节密钥的十六进制值,<packet-iv-hex>为数据包中的IV十六进制(即66697865645f69765f31366279746573) echo "df2d421529ca6c779d6003ef4f1dfaa944853980b3e19dd1e921ece27c9c8c2314406d52f940f565816799600ccde2e8" | xxd -r -p | openssl aes-128-cbc -d -K <your-key-hex> -iv <packet-iv-hex> | xxd -p
额外验证建议
- 用Scapy自带解密功能校验:加载捕获的数据包,用相同的
SecurityAssociation调用decrypt方法,对比解密结果,确认明文结构正确性。 - 确认ESP载荷范围:确保解密的是ESP头部(SPI、序列号)之后的密文部分,即数据包中
0x0030偏移开始的内容。
内容的提问来源于stack exchange,提问作者RupeshCh
相关产品推荐
相关产品推荐

