SBOM 标准与格式:SPDX、CycloneDX、SWID 详解
聊 SBOM,绕不开格式问题。市面上主流的就三种:SPDX、CycloneDX 和 SWID。很多人问我该选哪个,我的回答通常是——先搞清楚它们各自长什么样,再谈选型。
这一节,我把这三种格式掰开揉碎讲清楚。你想想看,如果连 SBOM 的“语言”都不懂,后续的审计和合规工作根本没法落地。
SPDX 格式详解
SPDX(Software Package Data Exchange)是 Linux 基金会旗下的标准。它诞生得最早,2011 年就出了第一个版本。我个人习惯把它叫做“老大哥”,因为它的生态最成熟,工具链最全。
SPDX 的核心思路是:用一套统一的字段来描述软件包的名称、版本、许可证、版权信息、文件校验和等。它的文档结构像一本“户口本”,每个软件包都有一页详细的档案。
一个典型的 SPDX 文档长这样:
SPDXVersion: SPDX-2.3
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: my-app-sbom
Creator: Tool: sbom-tool-1.0
Created: 2024-01-15T10:00:00Z
## Package Information
PackageName: openssl
SPDXID: SPDXRef-Package-openssl
PackageVersion: 1.1.1t
PackageDownloadLocation: https://www.openssl.org/source/openssl-1.1.1t.tar.gz
PackageLicenseConcluded: OpenSSL
PackageLicenseDeclared: OpenSSL
PackageCopyrightText: Copyright (c) 1998-2023 The OpenSSL Project
嗯,这里要注意:SPDX 的字段名是大小写敏感的,而且每个包必须有一个唯一的 SPDXID。我在项目中遇到过有人把两个包的 ID 写重复了,结果解析工具直接报错,排查了半天。
PackageLicenseConcluded 和 PackageLicenseDeclared 是两个不同的字段。前者是你审计后得出的结论,后者是包本身声明的许可证。千万别混用,审计时会出大问题。
CycloneDX 格式详解
CycloneDX 是 OWASP 社区推出的标准。它比 SPDX 年轻,但发展很快。为什么?因为它专为“安全”而生。说白了,SPDX 更像一个“通用档案”,而 CycloneDX 从一开始就瞄准了漏洞管理和依赖分析。
CycloneDX 使用 JSON 或 XML 格式,结构更紧凑,更适合程序处理。它的核心概念是 Bom(Bill of Materials),每个组件都可以携带丰富的安全元数据,比如漏洞引用、哈希值、组件类型等。
一个典型的 CycloneDX JSON 片段:
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "openssl",
"version": "1.1.1t",
"purl": "pkg:generic/openssl@1.1.1t",
"hashes": [
{
"alg": "SHA-256",
"value": "a0b1c2d3e4f5..."
}
],
"licenses": [
{
"license": {
"id": "OpenSSL"
}
}
]
}
]
}
你看,CycloneDX 里有个 purl 字段,这是 Package URL 的缩写。它能把一个组件在全球范围内唯一标识出来。我曾经用这个字段做跨项目的依赖合并,效果非常好。
specVersion 一定要写对。我见过有人用 1.4 的解析器去读 1.5 的文档,结果 services 和 formulation 这些新字段全被忽略了。版本对齐很重要。
SWID 标签介绍
SWID(Software Identification Tag)是 ISO/IEC 19770-2 标准。它跟前面两个不太一样——SWID 是 由软件安装包自带的,而不是事后生成的。你可以把它理解成软件的“身份证”,安装时就贴在软件上了。
SWID 使用 XML 格式,结构相对固定。它的核心元素是 SoftwareIdentity,里面包含名称、版本、制造商、注册表项等。SWID 最大的优势是:它跟操作系统和包管理器的集成度很高。比如 Windows 10/11 的很多系统组件都自带 SWID 标签。
一个简化的 SWID 示例:
<SoftwareIdentity
xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd"
name="OpenSSL"
version="1.1.1t"
versionScheme="multipartnumeric">
<Entity
name="OpenSSL Foundation"
regid="regid.2023-01.openssl.org" />
<Evidence>
<Directory path="C:\Program Files\OpenSSL" />
</Evidence>
</SoftwareIdentity>
SWID 的缺点也很明显:它只覆盖安装了 SWID 标签的软件。对于开源组件、自编译软件、脚本语言包,SWID 基本无能为力。所以它通常作为辅助手段,跟 SPDX 或 CycloneDX 配合使用。
三种格式对比与选型
讲完了各自的特点,我们来做个横向对比。我整理了一张表,方便你快速决策:
| 维度 | SPDX | CycloneDX | SWID |
|---|---|---|---|
| 标准化组织 | Linux Foundation | OWASP | ISO/IEC |
| 主要格式 | Tag-Value / RDF / JSON | JSON / XML | XML |
| 核心用途 | 许可证合规、版权审计 | 漏洞管理、依赖分析 | 软件资产识别、安装管理 |
| 生成方式 | 事后扫描生成 | 事后扫描生成 | 安装时自带 |
| 工具生态 | 非常成熟(FOSSology、ORT) | 快速增长(Dependency-Track、Grype) | 有限(OSIS、SWID Tool) |
| 漏洞关联 | 需额外映射 | 原生支持 | 需额外映射 |
| 适用场景 | 法律合规、开源审计 | DevSecOps、CI/CD 集成 | 企业资产管理、Windows 环境 |
怎么选?我个人的经验是:
- 如果你的主要目标是许可证合规(比如要过开源审计),选 SPDX。它的许可证字段最丰富,法律团队也最认可。
- 如果你的主要目标是漏洞管理(比如在 CI/CD 里做依赖扫描),选 CycloneDX。它跟 OWASP Dependency-Track、Grype 等工具配合得天衣无缝。
- 如果你需要做企业级的软件资产盘点(比如 Windows 环境下的软件清单),用 SWID 作为补充。
当然,现实情况往往是混合使用。我在一个大型项目中,就同时用了 SPDX 做许可证审计,CycloneDX 做漏洞扫描,SWID 做资产登记。三种格式各司其职,互不冲突。
三种格式的关系图
为了让你更直观地理解它们之间的关系,我画了一张图:
这张图把三种格式的核心定位和关系说清楚了。它们不是竞争关系,而是互补关系。你完全可以根据自己的场景,选择一种或多种组合使用。