• 基于项目工程构建SBOM(软件物料清单)的研究


    最近公司启动了一个新医疗项目,最终需要在国外注册使用(如美国FDA,欧盟),因此项目全生命周期管理过程必须严格,为满足合规要求,其中必不可少的一步是生成SBOM(软件物料清单)。临时给安排一个任务,来研究SBOM的生成。涉及到四个SBOM生成工具,sbom-tool,DycloneDX,Sift,ORT。然后就开发语言来说,公司项目有三种模式,纯C#项目,C++和C#混合使用的项目,纯C++项目,这里就最近几天的研究心得做一个总结。

    sbom-tool
    SBOM Tool是我最先开始,毕竟本人主要从事C#开发,而SBOM Tool(SBOM Tool.exe)是微软开发的开源命令行工具,用于自动生成和验证符合SPDX 2.2/3.0标准的软件物料清单(SBOM),支持跨平台安装和多种使用场景。这里安装方法就不做介绍,网上资料搜下就是,包括后续几种工具安装都不做介绍。我这里是作为dotnet工具全局安装的。可以直接在windows系统的CMD命令下,定位到工程编译之后的输出目录,使用类似如下的关键的命令来生成SBOM。若是要持续的集成CD/CI,在Visual Studio开发工具下,也可以在项目工程上右键->属性->生成->项目的生成成功后的事件中植入此命令,来对每次的构建都重新生成新的sbom。当然也可以将命令作为一个.bat批处理文件,在项目生成成功后来执行此文件来处理SBOM的生成。

    直接CMD中使用示例1:sbom-tool generate -b 项目工程编译之后的输出目录 -pn "MyApp" -pv "1.0.0" -ps 供应商名称 -m ./sbom-output

    sbom-tool构建SBOM关键参数和示例
    -b:构建产物的根目录,即代码编译之后的输出目录
    -bc: 项目源码目录,生成时的一些元数据会通过源码获取到,非必须.
    -pn: 包名称,建议显示指定
    -pv:包版本号
    -ps:包的供应商信息,指定包名称后不能为空
    -m:  指定生成的SBOM的输出目录,-D强制删除已有目录。
    -bl: 指定包含的文件,创建一个包含文件列表的文本文本,每个文件使用完整路径单独一行,使用此参数工具只会处理生成列表中明确指定的文件
    
    在工程文件的生成后事件配置执行sbom生成命令代码,我这里代码是注释的状态:
    	
    	<Target Name="GenerateSBOM" AfterTargets="Build">
    		
    		
    		
    		
    	Target>
    
    

    我这里首先是针对C#的项目使用sbom-tool工具进行SBOM生成,这个生成的是符合SPDX标准的SBOM,这个过程中确实很顺利,使用简单的命令运行立马出来结果,但当我需要排除一些文件或组件时,确发现sbom-tool无对应的命令来排除文件,当然,其提供了-bl命令参数来指定只对那些文件生成SBOM。然后针对深度依赖,即嵌套依赖问题识别不友好或者说识别不了,查阅下来说需要借助与其他手段或工具,针对C++项目也是如此。

    CycloneDX
    此时就开始了对第二个工具CycloneDX的研究,这个工具生成的是符合CycloneDX标准的SBOM,这里我也是将其作为dotnet工具进行全局安装的(安装命令:dotnet tool install --global CycloneDX),需要注意的是不要使用旧的项目,如.NET Framework的项目来使用此工具,我这边就是在NET Framework中使用了此工具进行生成,怎么走都没通,之前就是忽略了网上AI资料所提的,SycloneDX for .NET目前不支持早期的版本,.NET Framework,.NET Core的早期版本(如NET Core 2.1,NET Core 3.1,NET Core 5.0),后来拿公司的一个.NET 8项目来尝试使用此CycloneDX,立马就能走通了。但在C#项目下,CycloneDX 默认情况下它会分析项目的 NuGet 包依赖(包括直接和传递依赖),但不会自动包含项目引用(Project References)所生成的 DLL 文件,因为这些 DLL 被视为“内部组件”而非外部第三方依赖。作为解决办法,从 CycloneDX .NET 工具 v2.0+ 开始,官方支持通过命令行参数显式包含项目引用。使用 --include-project-references 参数,注意,此时就需要使用工程目录,而不能使用解决方案目录,即.csproj文件,而非.sln文件。在只有.dll文件,即随便拷贝一个外部无用的.DLL文件放在编译后的输出目录中,CycloneDX .NET不会自动识别其组成,即SBOM中没有此项。若需要的话可以将其作为一个NuGet私有源进行引入。

    使用CycloneDX生成SBOM的参考命令:
    命令示例:dotnet cyclonedx ..\CSharp_Sbom.sln --output-format json --exclude-dev --exclude-test-projects -sn YourCompany -sv 1.0.0 -o ..\SbomScript\CycloneDX_sbom -fn sbom.json
    image

    在C#项目中使用CycloneDX工具时,也是顺利的生成了需要的SBOM,但是当在C++项目上生成时,这里先说下,使用的C++项目时临时创建的,无标准的包管理器,也没有用CMake,Conan或vcpkg管理依赖。最终生成出来的sbom文件中确没有任何组件或者说没有任何依赖,也就是json文件中的dependencies元素里面没有包含任何东西。也就是无法直接使用这个工具来生成C++项目的SBOM,这就尴尬了。后来查资料大概意思是说:因为C++缺乏统一的依赖管理机制(如 Java 的 Maven 或 Node.js 的 npm , C#的NuGet),不能直接解析依赖信息。

    Syft
    然后就开始了我的第三个工具Syft的研究,Syft会自动扫描,检测构建产物中的二进制文件和动态链接库来识别第三方组件,自动识别提取生成依赖包,并输出SBOM。支持格式:CycloneDX、SPDX、Syft JSON 等,是由 Anchore 开发的开源 CLI 工具,是Go语言编写。
    Syft生成SBOM参考命令: syft . -o cyclonedx-json=../../sbom/syft/syft.cdx.json -vv
    5E7673D9-61DC-4829-8EC9-FA8C3A1B5E65
    526ABF57-406F-4c90-B9F8-CA122919BA9A
    -v 输出警告信息
    -vv 输出调试信息
    使用Syft确实能做到自动识别C++的项目生成SBOM,但也仅仅是有限的支持,即仅能识别已知特征的库,无法还原完整依赖树(尤其静态链接、动态加载的以及自定义编译的库),只因C++项目无包管理器或者说有些C++项目没有使用统一的一套包管理流程,纯 CMake/Makefile + 静态链接情况下,只有Syft可行。能从二进制中识别 OpenSSL、zlib、libpng、glibc 等常见库(即使静态链接),经过一番折腾,这里又看到了另外一个工具OSS Review Toolkit (ORT) ,但经过了解下来说这是一个全流程的合规审计工具,因为目前只需要一个SBOM快速生成工具,貌似学习使用曲线更高,一下子就吓到了我这种懒人,也就懒得研究了。
    最后附上一个简单的总结对比说明:
    5A97EFF3-207F-4f25-8E47-D2A8870A1A20

  • 相关阅读:
    sgu 176 Flow construction (有源汇的上下界最小流)
    java synchronized
    java计算机毕业设计远程教学系统录屏源程序+mysql+系统+lw文档+远程调试
    JSP 人力资源管理系统myeclipse开发mysql数据库BS模式java编程网页设计
    whip和whep
    UI美工设计岗位的基本职责概述(合集)
    Seurat | 完美整合单细胞测序数据(部分交集数据的整合)(一)
    tkinter模块解读和使用
    算法篇------贪心1
    pgsql误删除pg_wal文件后,服务启动失败
  • 原文地址:https://www.cnblogs.com/huangqian/p/19575355