You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.,.'{

解决方案

问题根源

  1. -nopad参数误用:ESP的填充符合PKCS#7规范,-nopad会阻止OpenSSL自动移除填充数据及后续的填充长度、下一个头部字段,导致解密结果混入无效数据。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 09:10:19