GoSuda

Go 标准加密库中 FIPS 140-2 和 FIPS 140-3 的实现结构

By Gosunuts views ...

FIPS 140 ( Federal Information Processing Standard Publication 140 )

FIPS 140 是由美国 NIST 制定的密码模块安全认证标准。该标准评估特定的密码模块或库是否满足 NIST 定义的安全要求。因此,通过 FIPS 140 认证意味着该模块具备官方认可的可信安全性,并表明其能够用于金融、医疗、国防等安全至关重要的领域。

自 1994 年首次制定以来,FIPS 140 分别于 2001 年修订为 FIPS 140-2,以及于 2019 年修订为 FIPS 140-3。迄今为止,许多系统和应用程序仍然要求 FIPS 140-2 或 FIPS 140-3 认证。

FIPS 140 与编程语言

由于这些原因,获得 FIPS 140 认证的密码模块在多种编程语言和环境中被当作事实上的标准使用。典型的例子包括 OpenSSL、BoringSSL、LibreSSL 以及 NSS 等,它们是安全关键型应用程序中最广泛应用的模块。

绝大多数 FIPS 140 认证模块都是使用 C 或 C++ 编写的。正因如此,在 PHP、Python、Javascript 等语言中,通常不直接使用这些模块,而是通过外部 Provider 模块进行联动的方式来构建 FIPS 环境。然而,这种方法存在若干局限性。

  • 版本不匹配问题

    FIPS 140 认证仅授予特定版本。因此,若要使用最新版本的模块,必须重新经历认证过程,在此过程中可能会导致应用程序使用的模块与 FIPS 认证模块之间出现版本不匹配。如果使用了未授权的版本,则该环境将不再被视为 FIPS 认证环境。

  • 动态加载与性能下降

    大多数语言以动态库的形式加载并使用 FIPS 140 认证模块。这种方式可能会在初始化和执行过程中导致性能下降,并且如果在运行时出现问题,存在直接影响整个应用程序稳定性的风险。

  • 安全漏洞

    如前所述,在类似 OpenSSL Provider 的外部模块联动结构中,该模块的安全漏洞存在直接传播至应用程序的风险。此外,应用程序与外部模块之间的通信层本身会成为额外的攻击面,并且需要一个独立的的安全层来对其进行保护。这会增加复杂性,从而产生意料之外的漏洞。

FIPS 140 与 Golang

出于这些原因,Golang 采取了不同的策略。Go 选择了一种不依赖外部工具、在官方加密库中直接支持 FIPS 140 认证的方式。因此,开发者无需安装或配置单独的 Provider,只需在继续使用标准 crypto 软件包的同时激活 FIPS 认证模式 (GOFIPS=1) 即可。在此过程中,消除了与外部模块的通信边界,从而增强了安全性,并且只需分发静态编译的单一二进制文件,从而简化了运维。

FIPS 140-2 与 Golang

为此,Golang 将派生自 BoringSSL 的 BoringCrypto 模块内嵌至 Go 运行时中,从而获得了 FIPS 140-2 认证。BoringCrypto 自 Go 1.19 版本起可在特定发行版中启用,通过此功能,Go 应用程序无需任何单独的外部模块即可构建 FIPS 140-2 认证环境。

然而,由于 BoringCrypto 基于 OpenSSL,因此 C 语言依赖性仍然存在。因此,Go 应用程序无法构建为完全独立的二进制文件,并伴随着必须同时分发所需 C 语言库的局限性。

FIPS 140-3 与 Golang

为了克服这些局限性,Go 团队根据 FIPS 140-3 规范改进了原有的 Go 标准 crypto 库。该改进型模块从 Go 1.21 版本开始以实验性质提供,目前正在接受 NIST 的 FIPS 140-3 认证审查。NIST FIPS 140-3 审查中的模块列表

这展现了 Go 加密库的成熟度,通过该库,Go 能够以完全独立的单一二进制文件提供 FIPS 140-3 认证环境。

此外,Go 团队不仅满足于达成 FIPS 140-3 标准,还进一步自主强化了安全性。

  • Fail Fast

    Go 的 FIPS 模式应用了 Fail Fast 安全模型,当调用未认证的算法时,会立即通过 panic 中止执行。这与其它语言的基于 Provider 的模型保留回退可能性的做法不同,在安全性和合规性方面提供了更严格且更明确的保证。

  • Hedged Signature

    在 FIPS 140-3 标准中,进行 ECDSA 签名时推荐使用 RFC6979 方式。然而,Go 在此基础之上引入了 Hedged 方式,从而能够更强有力地应对签名过程中可能出现的侧信道攻击。

  • 增强型随机数生成器

    Go 的随机数生成器在采用用户空间 DRBG (Deterministic Random Bit Generator) 的同时,额外注入了针对操作系统内核的熵,从而不仅在用户空间,在内核空间也能生成高质量的随机数。通过该机制,进一步增强了随机数生成器的安全性。