SBOM 标准与格式:SPDX、CycloneDX 与 SWID 详解
聊 SBOM,绕不开格式问题。我记得刚接触软件供应链安全那会儿,市面上主流的格式就有三四种,每个都说自己是标准。你想想看,如果连格式都不统一,上下游怎么交换数据?
目前公认的三大格式是:SPDX、CycloneDX 和 SWID。它们各有各的出身和侧重点。这一节,我把它们掰开揉碎了讲清楚。
SPDX 格式详解
SPDX(Software Package Data Exchange)是 Linux 基金会旗下的项目。它诞生得最早,2011 年就发布了第一个版本。我个人习惯把它叫做“老大哥”,因为它的生态最成熟,覆盖面也最广。
SPDX 的核心思想是:一份文档说清楚一个软件包的所有信息。包括许可证、版权、文件列表、校验和等等。
来看一个 SPDX 2.3 的片段:
SPDXVersion: SPDX-2.3
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: my-app-sbom
CreationInfo:
Creators: Tool: sbom-tool-1.0
Created: 2024-01-15T10:00:00Z
PackageName: log4j-core
SPDXID: SPDXRef-Package-log4j-core
PackageVersion: 2.17.1
PackageDownloadLocation: https://repo.maven.apache.org/...
PackageLicenseConcluded: Apache-2.0
PackageLicenseDeclared: Apache-2.0
PackageCopyrightText: Copyright 2023 The Apache Software Foundation
看到没?它用键值对的方式组织数据,可读性很强。每个包都有一个唯一的 SPDXID,方便互相引用。
核心优势:许可证管理能力极强。SPDX 维护了一个庞大的许可证列表(SPDX License List),几乎涵盖了所有开源许可证。如果你需要做许可证合规审计,SPDX 是首选。
我在项目中遇到过一个问题:某个第三方组件声明了 MIT 许可证,但实际代码里混入了 GPL 的代码。用 SPDX 的 PackageLicenseConcluded 和 PackageLicenseDeclared 字段,就能清晰区分“声明”和“实际结论”,这个设计很巧妙。
CycloneDX 格式详解
CycloneDX 是 OWASP 社区推出的标准。它更轻量,专为安全场景设计。说白了,SPDX 像一本百科全书,CycloneDX 像一本安全手册。
CycloneDX 使用 JSON 或 XML 格式,对机器解析非常友好。来看一个 JSON 示例:
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "log4j-core",
"version": "2.17.1",
"purl": "pkg:maven/org.apache.logging.log4j/log4j-core@2.17.1",
"licenses": [
{
"license": {
"id": "Apache-2.0"
}
}
],
"properties": [
{
"name": "owasp:severity",
"value": "critical"
}
]
}
]
}
注意那个 purl 字段。它是 Package URL 的缩写,能唯一标识一个组件及其版本。我建议你在生成 SBOM 时,一定要带上 purl,这样后续做漏洞匹配会方便很多。
我的经验:CycloneDX 对容器镜像的支持很好。它可以直接描述镜像的层(layers)和依赖关系。如果你做容器安全,CycloneDX 会让你省不少力气。
CycloneDX 还有一个杀手锏:组件元数据。你可以给每个组件打标签,比如标记它是“测试依赖”还是“生产依赖”。这在做风险分析时非常有用。
SWID 标签介绍
SWID(Software Identification)标签是 ISO/IEC 19770-2 标准。它跟前面两个不太一样——它更关注软件安装后的识别和管理。
SWID 标签通常由软件厂商生成,随安装包一起发布。它的结构是 XML 格式,核心元素包括:
- Entity:软件发布者信息
- Meta:软件名称、版本、唯一 ID
- Payload:安装文件列表和校验和
- Evidence:安装路径、注册表项等
一个简化的 SWID 标签示例:
<SoftwareIdentity
xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd"
name="MyApp"
version="3.1.0"
tagId="com.example.myapp-3.1.0">
<Entity name="Example Corp" role="softwareCreator"/>
<Meta product="MyApp" />
<Payload>
<File name="myapp.exe" size="1048576" />
</Payload>
</SoftwareIdentity>
注意:SWID 标签的生成方通常是软件厂商,而不是使用者。如果你用的是第三方商业软件,可以找厂商要 SWID 标签。但对于开源软件,SWID 的覆盖率远不如 SPDX 和 CycloneDX。
我曾经帮一家金融客户做软件资产盘点。他们采购了上百款商业软件,但只有不到 30% 的厂商提供了 SWID 标签。最后我们不得不自己写脚本,从安装目录和注册表中反向生成 SWID 信息。这个过程很痛苦,但也让我深刻理解了 SWID 的定位——它更适合“软件资产管理”,而不是“开源组件分析”。
格式对比与选型
三种格式各有千秋。我整理了一张对比表,方便你快速决策:
| 维度 | SPDX | CycloneDX | SWID |
|---|---|---|---|
| 标准组织 | Linux Foundation | OWASP | ISO/IEC |
| 核心场景 | 许可证合规 | 安全漏洞管理 | 软件资产管理 |
| 数据格式 | Tag-value / JSON / XML | JSON / XML | XML |
| 组件标识 | SPDXID | purl / cpe | tagId |
| 许可证描述 | 非常详细 | 较详细 | 简单 |
| 依赖关系 | 支持 | 支持(深度依赖) | 有限 |
| 工具生态 | 成熟 | 快速增长 | 一般 |
怎么选?我给出几条建议:
- 如果你主要做许可证合规:选 SPDX。它的许可证列表最全,法律团队也最认可。
- 如果你主要做安全漏洞管理:选 CycloneDX。它跟 OWASP Dependency-Track、VEX 等工具配合得天衣无缝。
- 如果你管理的是商业软件资产:选 SWID。它跟 CMDB、ITAM 系统集成更方便。
- 如果你需要通用方案:我建议同时生成 SPDX 和 CycloneDX。很多工具都支持多格式输出,多一份总比少一份好。
下面这张图展示了三种格式在软件供应链中的定位差异:
最后说一句:格式只是载体,数据质量才是关键。不管你选哪种格式,都要确保 SBOM 中的组件信息准确、完整、及时更新。否则,再好的格式也只是一堆没用的数据。