
随着汽车行业加速迈向高度互联和自动驾驶时代,嵌入式软件开发中网络安全的重要性空前凸显。那么,如何为汽车网络安全选择合适的编程语言?
本文将探讨编程语言的选择如何影响汽车系统的网络安全和软件质量,并评估八种主流编程语言------C、C++、Java、Kotlin、Python、C#、JavaScript 和 Rust------在 AUTOSAR 平台及安全关键型开发环境下的适用性。
汽车安全标准考量
现代汽车是高度复杂、由软件驱动的系统。随着系统复杂性的增加,攻击面也不断扩大,使得网络安全成为重中之重。根据 Perforce 《汽车软件开发报告》,安全问题连续多年位列开发者最关注的三大问题之一。
为应对这些挑战,开发者必须遵循 ISO/SAE 21434 等标准,该标准规范了道路车辆的网络安全工程。尽管 ISO 25010 软件质量模型中定义的通用软件质量特性并非强制要求,但它们对汽车软件依然具有相关性。然而,2025 年的报告中有 22% 的受访者指出,满足此类标准的安全要求既困难又耗时。
因此,为汽车网络安全选择编程语言时,需要充分考虑标准要求。编程语言在满足这些标准方面起着关键作用,其影响范围涵盖模块化、抽象化能力乃至抵御漏洞的韧性等方方面面。
ISO/SAE 21434:网络安全工程
ISO/SAE 21434 是一项较新的汽车标准,用于管理道路车辆电子系统的网络安全风险。尽管该标准出台时间不长,但根据 2025 年 Perforce《汽车软件开发报告》,79% 的受访者所在企业已被要求遵守 ISO/SAE 21434标准。
该标准对软件开发提出了明确要求,包括分析软件是否存在固有弱点,以及整体在网络安全需求方面的一致性、正确性和完整性。它还列出了选择编程语言时应考虑的标准,例如安全设计和编码技术,以及明确的语法与语义定义。
此外,它还包含语言本身未涉及的语言标准。这可以通过多种方式实现。最常见的方式是使用定义语言安全子集的编码标准。例如,C语言最常使用 MISRA C 规范。MISRA C 定义了基本的类型系统,以防止C语言中与隐式类型转换相关的问题。这是强类型(strong typing)系统的典型示例。
您可以借助 Perforce QAC 和 Klocwork 等静态分析工具,轻松检查代码是否符合编码规范。
在本文对比中,我们采用以下术语来概括编程语言的特性:
-
**语言(Language):**指语言标准的质量,即是否对任意程序的语法正确性和语义有清晰定义。
-
**特性(Features):**指语言功能的丰富程度,可以支持现代编程范式,方便编写安全可靠的软件。
-
**指导(Guidance):**指支持该语言的文档和工具的可用性,包括编码规范和静态分析工具。
-
**集成(Integration):**指该语言编写的程序与其他语言编写的程序交互的难易程度。
-
**韧性(Resilience):**指是否具备防止语言被不当使用的方法,这是语言工具链和静态分析工具保护的结合。
ISO 25010:软件质量模型
ISO 25010 定义了 8 项质量特性和 31 项子特性。
编程语言需要提供相应功能,以便开发者能够开发出具备这些质量特性的软件。
"安全性"是其中一项特性,但需要评估所有质量特性在多大程度上被编程语言所支持。对于实时应用而言,"功能适用性"和"性能效率"同样重要。
此外,对于汽车项目而言,"可维护性"非常重要,因其高度依赖组件复用;"可移植性"也十分关键,以便能够轻松适配新的硬件。
AUTOSAR 平台
AUTomotive Open System ARchitecture(AUTOSAR,汽车开放系统架构)旨在标准化并确保基础软件元件、接口和总线系统的未来适应性,以帮助整车厂在控制成本的同时,管理日益增长的系统复杂性。
其中,Classic Platform API 面向具有严格实时要求和安全关键性的车辆功能,使用 C 语言定义;而面向联网与自动驾驶的新一代 Adaptive Platform API 则使用 C++语言。不过,Adaptive Platform 明确支持引入其他语言的绑定。
接下来,除了 C 和 C++,我们还将综合评估其他主流的编程语言------Python、Java、C#、JavaScript、Go 和 Rust,共同分析这些语言的质量特性,以及如何缓解其潜在缺陷。
不同编程语言的评估
原生语言(Native Languages)
原生语言被编译为目标代码,可直接在目标机器上执行。按初始发布日期排序,这些语言依次包括 C、C++、Rust 和 Go。
C 和 C++
原生执行存在安全与可靠性隐患:程序错误可能导致崩溃,安全漏洞也可能被利用。ISO 维护着 C 和 C++ 的语言标准,标准中明确规定了问题行为。C 和 C++ 可能表现出多种未定义行为(例如使用未初始化的数据、空指针解引用或缓冲区溢出)。
幸运的是,这些问题已被充分认知,且存在诸如MISRA C 和 MISRA C++ 等编码规范,以有效缓解未定义行为。静态分析工具如Perforce QAC 和 Klocwork 可用于强制执行这些规范。
原生语言天生具备高性能优势。C 和 C++ 能够提供最高级别的执行控制,从而实现最佳的运行时性能和内存效率。但这也带来了内存访问错误的风险,例如内存释放后使用。编码规范可在此方面提供指导:MISRA C 明确禁止使用动态内存;而在 C++ 中,可利用"作用域绑定资源管理"(SBRM)实现内存管理自动化。
Go
Go 语言由 Google 于 2009 年发布,设计上强调并发执行。它允许像C语言一样手动管理内存(伴随着相应风险),也支持使用垃圾回收器(GC)进行内存自动管理(但会引入非确定性),因此不适用于实时应用。
Rust
《Rust 参考手册》描述了 Rust 编程语言,Ferrocene 工具链则包含了语言规范。
Rust 提供了一种基于"所有权"机制的新型动态内存管理方案。它规定了程序必须遵守的所有权规则,这些规则用于自动化内存管理,类似于 C++ SBRM。这意味着编写正确的程序更难,但生成的代码无需垃圾回收,适用于实时应用。语言规则确保安全的Rust代码不会出现空指针解引用、缓冲区溢出或数据竞争等错误。对于不安全的代码,则无法提供此类保证。
新成立的"安全关键型 Rust 联盟"(Safety-Critical Rust Consortium)正致力于制定更完善的安全指南。Perforce 已经开发出适用于 Rust 的 MISRA C 子集,并计划在即将发布的 Perforce QAC 版本中推出。
总结来说:
-
就语言特性而言,C 语言仅支持过程式编程,而其他语言均支持现代编程范式。
-
C 编译器几乎支持所有硬件平台;C++ 编译器覆盖其中的绝大多数平台;Rust 利用 LLVM 技术编译为原生代码,支持广泛的架构;而 Go 仅支持桌面平台。
-
由于 C++ 基于 C语言,可以直接在 C++ 程序中调用 C 代码。又因为 C 是上述语言中最古老且最简单的,而其他语言的编译器或运行时环境通常是以 C/C++ 实现,因此 C 代码可以集成到几乎所有环境中。
-
C++ 的集成相对复杂,因其应用二进制接口(ABI)可能变化且存在名称修饰(name mangling)问题,但对于多数语言已提供解决方案。
-
Rust 与 C 语言的兼容性非常好,并支持 C++。Rust 基金会已启动"C++/Rust 互操作性计划",旨在为 C++ 开发成熟且标准化的解决方案。
-
Go 不支持直接调用 C/C++ 函数,但可以通过生成封装器(wrapper)实现交互------这些封装器依赖于所使用的 Go 编译器。
平台语言(Platform Languages)
ava 与 Kotlin
平台为底层硬件机器提供了抽象层。它包含一个编译器,用于为虚拟机生成字节码。Java 和 Kotlin 运行在 Java 平台上,依赖 Java 虚拟机(JVM);C# 则是 Microsoft .NET 平台的主要语言,该平台使用通用语言运行时(CLR)。
程序的执行完全由虚拟机的规范所定义。然而,它们通常配有垃圾回收器,可能会引入非确定性。尽管也存在具备抢占式、确定性垃圾回收器的实时 Java 平台,程序仍可能出现缺陷和安全问题。因此,我们建议遵循 Java 的 CERT 编码规范,参考CWE 提供的漏洞列表,以及 OWASP 针对这两大平台提供的安全速查指南。
Google 指定 Kotlin 作为 Android 移动平台的主要编程语言(此前为 Java)。Android 提供了成熟的原生开发套件(NDK),支持 C 和 C++,并于 2021 年新增 Rust 作为选项。
Java 适用于常见的桌面和服务器平台;.NET 则主要在 Windows 上获得良好支持。
在集成方面,平台支持不同的实现方式。JDK提供了常规的集成模式:平台为本机编程语言提供C语言API(jni.h),使原生代码能够与Java虚拟机交互。.NET 框架同样支持此类集成。但.NET 更进一步:它还为多种语言提供编译器,其组件可以直接在源代码层面交互。需要注意的是,不同的语言之间可能存在细微的语义差异。例如 Java 与 Kotlin 虽然都能在 Java虚拟机中直接交互,但 Kotlin 在空值安全方面比Java更强,这类差异必须加以考虑。
最后,.NET 框架还支持与 COM 组件库的互操作,而 Python.NET 则实现了 Python 与所有 .NET 语言之间的互操作。
解释型语言(Interpreted Languages)
剩余的两种语言------Python 和 JavaScript,属于解释型语言。解释器逐行读取程序并执行指令,这使得它们成为确定性最低、最不适用于实时系统的语言。
Python
Python 是一种流行的脚本语言,运行速度较慢但易于编写。它常被用作"粘合剂",用于连接由原生语言编写的高性能组件。这种集成属于系统级集成,即通过系统调用来执行可执行的程序。在语言层面,Python 提供了 C语言 API,来编写运行在Python解释器中并与之交互的 C 代码。Python 的流行,部分源于它拥有大量高效的的第三方包(库),这些包可利用原生代码处理XML解析等常见任务。
JavaScript
JavaScript 是用于定义网页行为的语言。目前,某些车载信息娱乐系统(IVI)正是以 Web 应用的形式实现,并使用 JavaScript。ECMA 负责维护 ECMAScript 标准,但实际中存在众多的语言变体和扩展。由于JavaScript 的版本、框架和运行环境种类繁多,必须充分理解操作环境,才能有效应用 CWE 和 OWASP 提供的指导建议。
在浏览器的互操作性方面,WebAssembly 能够将多种编程语言编译为可在网页浏览器中高效执行的目标代码。
对比分析
下表汇总了上文的所述内容,分别从 ISO/SAE 21434 和 ISO 25010 角度评估各语言的适用性。
ISO/SAE 21434 适用性:

ISO 25010 适用性:

如何确定适用于汽车网络安全的编程语言
语言的适用性取决于项目的安全完整性等级(SIL)。对于安全关键型项目,可能需要采用经过认证的工具链,这将会大幅缩小可选范围。
-
在硬件资源有限且实时性要求严格的环境中,C语言仍是简单应用的理想选择。
-
C++ 在复杂的分层框架中更为适用,例如 AUTOSAR 自适应平台,其 API 以 C++ 进行定义。
-
Java 适用于Android等 Java 框架内部,或在采用实时 JVM 的实时环境中。Kotlin 同样适用于 Android 开发,但其稳定性略逊于 Java,实时支持也较弱;不过,它在车载信息娱乐系统(IVI)中与 JavaScript 的集成表现更佳。
-
C# 适用于 .NET 平台,但该平台目前并未应用于汽车领域。
-
Python 仅适用于少数特定场景,且通常存在更合适的替代方案。
-
JavaScript 对于基于 Web 的车载信息娱乐系统(IVI)用户界面至关重要。
-
Rust 提供更强的安全保障,并且随着新兴指导和认证工具链的出现,越来越受欢迎。
随着汽车行业的持续发展,我们的工具和实践也必须同步升级。编程语言的选择不仅是一项技术决策,更是一项战略决策,直接影响系统的安全性、网络安全性和长期可维护性。
利用 Perforce 静态分析工具提升汽车网络安全(支持C、C++、C#、Python、Java、JavaScript 和 Kotlin)
在汽车网络安全领域,选择合适的静态分析工具与选择合适的编程语言同样重要。
Perforce 静态分析工具 QAC和 Klocwork 能够在开发者编写代码的同时,及时检测网络安全漏洞,从而持续保障软件质量。
Perforce QAC 与 Klocwork 还能强制执行 ISO/SAE 21434 等安全标准,并对 MISRA 等安全关键型编码规范中的违规行为进行标记。
Perforce中国授权合作伙伴------龙智:
电话:400-666-7732
邮箱:marketing@shdsd.com