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 格式定位对比 开发阶段 构建阶段 部署阶段 SPDX 许可证合规 文件级溯源 CycloneDX 安全漏洞管理 依赖关系分析 SWID 软件资产管理 安装后识别 选型建议 • 许可证合规 → SPDX • 安全漏洞管理 → CycloneDX • 软件资产管理 → SWID • 通用方案 → SPDX + CycloneDX 同时生成

最后说一句:格式只是载体,数据质量才是关键。不管你选哪种格式,都要确保 SBOM 中的组件信息准确、完整、及时更新。否则,再好的格式也只是一堆没用的数据。