2、SBOM标准与格式:SPDX、CycloneDX、SWID标准介绍,JSON/XML格式解析
聊SBOM,绕不开的就是标准。我见过不少团队,一开始自己搞了一套“自定义格式”,结果跟上下游对接时,对方根本不认。说白了,SBOM的价值在于交换,交换就得有共同语言。目前业界公认的三大标准:SPDX、CycloneDX、SWID。咱们一个一个说清楚。
2.1 三大标准:谁是谁?
这三个标准,定位不太一样。我习惯用一个比喻:SPDX像身份证,CycloneDX像体检报告,SWID像户口本。你想想看,是不是这个理?
| 标准 | 维护组织 | 核心定位 | 我的经验 |
|---|---|---|---|
| SPDX | Linux基金会 | 许可证合规、组件清单 | 做开源合规审计,首选它 |
| CycloneDX | OWASP | 安全漏洞、依赖关系 | 做安全运维,我推荐它 |
| SWID | ISO/IEC | 软件身份识别、资产管理 | 企业级设备管理,它最对口 |
关键点:没有哪个标准是“万能钥匙”。我在项目中通常是混合使用——设备端用SWID做身份注册,安全审计时用CycloneDX,许可证合规用SPDX。各取所长。
2.2 SPDX:许可证合规的老大哥
SPDX(Software Package Data Exchange)是资历最老的。我记得2011年它刚出来时,大家还在争论“许可证信息要不要写进代码里”。现在呢?已经是行业标配了。
SPDX 2.3版本的核心结构,我总结为“三件套”:
- SPDX Document:文档头,包含版本、创建者、时间戳
- Package Information:每个组件的名称、版本、下载地址、校验和
- License Information:许可证ID、许可证文本、结论
给你看个JSON片段,这是我实际项目中生成的:
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "设备管理平台-v3.2.1",
"creationInfo": {
"created": "2025-03-15T10:30:00Z",
"creators": ["Tool: sbom-tool-1.0", "Organization: 某科技公司"]
},
"packages": [
{
"SPDXID": "SPDXRef-Package-001",
"name": "OpenSSL",
"versionInfo": "1.1.1w",
"licenseConcluded": "OpenSSL",
"checksums": [{"algorithm": "SHA256", "value": "a1b2c3..."}]
}
]
}
避坑指南:我曾经遇到一个项目,SPDX文件里licenseConcluded字段写的是“MIT”,但实际代码里混了GPL的代码。结果法务部门找上门来……嗯,从那以后我每次生成SPDX都会做一次许可证扫描比对,确保concluded和declared一致。
2.3 CycloneDX:安全运维的利器
CycloneDX是OWASP家的孩子,天生就带着安全基因。它比SPDX更轻量,但对漏洞信息的支持更细致。我个人习惯在做容器镜像扫描时,首选CycloneDX格式。
它的核心字段,我列几个重点:
- bomFormat:固定为"CycloneDX"
- components:组件列表,支持嵌套(比如容器里套应用)
- vulnerabilities:漏洞列表,直接关联CVE编号
- services:服务依赖(这个SPDX没有)
XML格式的示例:
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.4" version="1">
<components>
<component type="library">
<name>log4j-core</name>
<version>2.17.1</version>
<licenses>
<license><id>Apache-2.0</id></license>
</licenses>
</component>
</components>
<vulnerabilities>
<vulnerability ref="CVE-2021-44228">
<ratings>
<rating>
<severity>critical</severity>
<score>10.0</score>
</rating>
</ratings>
</vulnerability>
</vulnerabilities>
</bom>
注意:CycloneDX的vulnerabilities字段是可选的。但如果你不做安全审计,那用CycloneDX的意义就少了一半。我见过有人只导出了components,漏洞信息全空——那还不如用SPDX呢。
2.4 SWID:设备管理的“身份证”
SWID(ISO/IEC 19770-2)是专门为软件资产管理设计的。它跟SPDX、CycloneDX最大的区别是:SWID标签是安装在设备上的。你想想看,企业里有成千上万台设备,每台装了什么软件、版本多少、授权给谁——SWID就是干这个的。
SWID标签的核心结构:
- Entity:软件发布者、管理者
- SoftwareIdentity:软件名称、版本、唯一ID
- MetaData:自定义扩展信息(比如设备序列号、安装路径)
- Payload:关联的文件清单(可选)
XML格式示例:
<SoftwareIdentity
xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd"
name="设备管理Agent"
version="4.2.0"
tagId="com.example.agent-4.2.0-x64">
<Entity name="某科技公司" role="softwareCreator"/>
<MetaData>
<Attribute name="deviceSerial" value="SN-2025-001"/>
<Attribute name="installPath" value="C:\Program Files\Agent"/>
</MetaData>
</SoftwareIdentity>
我的习惯:SWID的tagId一定要做到全局唯一。我通常用“公司域名+软件名+版本+架构”的格式,这样即使跨部门、跨系统也不会冲突。曾经有个项目,两个团队用了相同的tagId,结果资产管理系统里数据全乱了……
2.5 JSON vs XML:怎么选?
这三个标准都支持JSON和XML。我个人的经验是:
| 场景 | 推荐格式 | 原因 |
|---|---|---|
| API接口传输 | JSON | 解析快、体积小、前端友好 |
| 配置文件/标签 | XML | Schema校验强、命名空间支持好 |
| 容器镜像扫描 | JSON | 工具链默认输出多为JSON |
| 企业资产管理 | XML | SWID标准原生就是XML |
说白了,没有绝对的好坏。我自己的做法是:内部系统用JSON,对外交换用XML。为什么?JSON处理起来快,但XML有Schema,对方能直接校验格式对不对。
2.6 一张图看懂三大标准的关系
下面这张图,是我自己总结的。它展示了三大标准在企业级设备管理中的定位和流转关系:
2.7 格式转换:一个实用技巧
实际工作中,你可能会遇到“甲方要SPDX,但工具只输出CycloneDX”的情况。别慌,有现成的转换工具。我常用的是sbom-converter这个开源项目。
基本用法:
# CycloneDX JSON 转 SPDX JSON
sbom-convert --from cyclonedx --to spdx \
--input sbom.cdx.json --output sbom.spdx.json
# SPDX 转 CycloneDX(带漏洞信息)
sbom-convert --from spdx --to cyclonedx \
--input sbom.spdx.json --output sbom.cdx.json \
--include-vulnerabilities
注意:转换不是万能的。SPDX的许可证字段和CycloneDX的漏洞字段,转换时可能会丢失部分信息。我建议:能原生生成就别转。实在要转,转换后一定要做一次字段完整性校验。
2.8 小结:选标准的三条原则
讲了这么多,最后给你三条我自己的选型原则:
- 看场景:许可证合规用SPDX,安全运维用CycloneDX,设备管理用SWID
- 看生态:你的工具链支持哪个?别为了标准去换工具
- 看对方:上下游合作伙伴用什么?统一标准能省去80%的对接成本