4、SOME/IP协议安全:SOME/IP协议基础、SOME/IP-SD的安全扩展、服务发现过程中的认证与授权

4.1 SOME/IP协议基础:别小看这个“快递员”

咱们做车载通信的,SOME/IP 这词儿肯定不陌生。说白了,它就是服务导向架构(SOA)在车上的“快递员”。你想想看,以前咱们用 CAN 总线,发个信号还得定义 ID、长度、位置,改起来特别麻烦。SOME/IP 就不一样了,它直接传输“服务”,比如“我要获取车速”、“请打开左转向灯”。

我个人习惯把 SOME/IP 理解为一种“远程过程调用”的变体。它定义了客户端怎么请求服务,服务端怎么响应。但这里有个关键点——它本身没有强制性的安全机制。嗯,这里要注意,SOME/IP 协议在设计之初,更多考虑的是性能和灵活性,而不是安全。

我在项目中遇到过,有些同事觉得 SOME/IP 跑在以太网上,有防火墙就万事大吉了。其实不然。SOME/IP 报文是明文传输的,你想想看,如果有人能接入车载网络,他完全可以伪造一个服务端,或者篡改你的请求数据。这可不是危言耸听。

⚠️ 警告: SOME/IP 协议本身不提供加密、认证或完整性保护。所有安全措施都需要在应用层或传输层额外实现。

咱们先看一个最简单的 SOME/IP 报文结构,你就明白了:

// SOME/IP 报文头部(固定长度 8 字节)
// 0                   1                   2                   3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |         Message ID            |           Length              |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |        Request ID             |       Protocol Version        |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Interface Version |  Message Type |     Return Code           |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |                    Payload (可变长度)                          |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

看到没?Message ID、Length、Request ID……全是明文。如果有人想搞破坏,他只需要知道这些字段的含义,就能伪造一个合法的 SOME/IP 报文。我曾经在测试中发现,一个简单的重放攻击就能让某个 ECU 误以为收到了合法的控制指令。

4.2 SOME/IP-SD 的安全扩展:给“快递员”加把锁

SOME/IP-SD(Service Discovery)是 SOME/IP 的“导航员”。它负责告诉客户端:“嘿,你要的服务在哪个 IP 地址、哪个端口上?” 这个过程如果被篡改,后果不堪设想。

标准 SOME/IP-SD 报文里,服务条目(Service Entry)和事件组条目(Eventgroup Entry)都是明文传输的。攻击者可以轻松地注入虚假的服务发现报文,让客户端连接到恶意服务端。这就是所谓的“中间人攻击”的一种变体。

那怎么解决呢?我建议在 SOME/IP-SD 的基础上,增加安全扩展。说白了,就是给每个服务发现报文加一个“数字签名”或者“消息认证码”。

具体来说,可以这么做:

  • 引入安全选项(Security Option):在 SOME/IP-SD 报文中增加一个新的选项字段,用于携带安全相关的信息,比如时间戳、随机数、签名等。
  • 使用 MAC(消息认证码):发送方用共享密钥对报文内容计算一个 MAC,接收方用同样的密钥验证。这样就能保证报文没有被篡改,并且来源是可信的。
  • 使用数字签名:如果密钥管理更复杂,可以用非对称加密。发送方用私钥签名,接收方用公钥验证。这样还能提供“不可否认性”。
💡 提示: 我个人习惯在项目初期就定义好安全扩展的格式。不要等到集成测试时才发现安全问题,那时候改起来成本就高了。

举个例子,一个带安全扩展的 SOME/IP-SD 报文可能长这样:

// 带安全扩展的 SOME/IP-SD 报文(简化示意)
// 标准 SOME/IP-SD 头部
// ...
// 服务条目列表
// ...
// 安全选项(新增)
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |   Option Type = 0x06 (Security) | Option Length = 0x0020     |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |   Security Algorithm (e.g., HMAC-SHA256)                      |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |   Timestamp (8 bytes)                                         |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |   Nonce (8 bytes)                                             |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |   Message Authentication Code (MAC) (16 bytes)                |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

这里的关键是,接收方在收到报文后,必须先验证 MAC,再处理服务条目。如果验证失败,直接丢弃报文。我曾经在项目中遇到过,因为忘记验证 MAC,导致一个伪造的服务发现报文被成功处理,差点让测试车跑偏了方向。

4.3 服务发现过程中的认证与授权:谁在敲门?能进吗?

服务发现过程,说白了就是“敲门”和“开门”的过程。客户端敲门(发送 Find Service 或 Subscribe Eventgroup),服务端开门(发送 Offer Service 或 Subscribe Eventgroup Ack)。但问题是,服务端怎么知道敲门的是“好人”还是“坏人”?

这里就需要引入“认证”和“授权”两个概念。

  • 认证(Authentication):确认客户端的身份。你是谁?
  • 授权(Authorization):确认客户端是否有权限访问该服务。你能干什么?

我建议在服务发现过程中,增加一个“握手”阶段。具体流程可以这样:

  1. 客户端发起认证请求:客户端发送一个特殊的 SOME/IP-SD 报文,里面包含自己的身份信息(比如数字证书)。
  2. 服务端验证身份:服务端验证客户端的证书是否有效,是否由可信的证书颁发机构(CA)签发。
  3. 服务端返回授权结果:如果认证通过,服务端根据预定义的访问控制列表(ACL),判断客户端是否有权限访问该服务。如果有,就正常回复 Offer Service;如果没有,就回复一个拒绝报文。
  4. 建立安全会话:认证和授权通过后,双方可以协商一个会话密钥,用于后续的 SOME/IP 通信加密。
🔑 核心要点: 认证和授权必须在服务发现阶段完成,而不是等到服务调用时。否则,攻击者可能已经通过服务发现获取了服务端的信息,然后发起攻击。

你想想看,如果服务端在收到 Find Service 后,不验证客户端身份就直接回复 Offer Service,那攻击者就能知道这个服务端的存在,以及它的 IP 地址和端口。接下来,他就可以针对这个服务端发起攻击了。

我在实际项目中,曾经设计过一个基于 PKI(公钥基础设施)的认证方案。每个 ECU 在出厂时都预置了一个数字证书。服务发现时,双方通过证书交换和验证,确保对方是合法的。同时,服务端还维护了一个 ACL,里面记录了哪些客户端可以访问哪些服务。比如,只有“网关”ECU 才能访问“远程诊断”服务,而“娱乐”ECU 则不行。

这里有一个避坑指南:我曾经遇到过,因为证书过期导致服务发现失败,整个系统都瘫痪了。所以,证书的生命周期管理一定要做好。建议在系统设计时,就考虑好证书的更新机制。

最后,总结一下服务发现过程中的安全要点:

安全环节 关键措施 常见风险
身份认证 使用数字证书或预共享密钥 证书伪造、密钥泄露
授权控制 基于 ACL 或策略引擎 ACL 配置错误、权限提升
消息完整性 使用 MAC 或数字签名 重放攻击、篡改攻击
会话安全 协商会话密钥,加密通信 密钥协商过程被攻击

嗯,说白了,SOME/IP 协议安全的核心就是:别让坏人轻易敲开门,也别让好人走错门。认证和授权,就是这两把锁。希望今天的分享能帮到你。