如何检查我的 golang 应用程序是否使用 Boringcrypto 而不是本机 golang crypto?

Kos*_*nou 9 fips go cgo

上下文:我正在阅读多篇有关使我的 golang 应用程序符合 FIPS 规范的文章(换句话说,使我的应用程序使用 Boringcrypto 而不是本机 golang 加密):

\n\n

简而言之,他们都说要跑

\n
# Build a binary and assert that it uses boringcrypto instead of the native golang crypto\nRUN GOEXPERIMENT=boringcrypto go build . && \\\n    go tool nm fips-echo-server > tags.txt && \\\n    grep \'_Cfunc__goboringcrypto_\' tags.txt 1> /dev/null\n
Run Code Online (Sandbox Code Playgroud)\n

然后期望以下输出:

\n
  e70fa0 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_cbc_encrypt\n  e70fc0 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_ctr128_encrypt\n  e70ff0 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_decrypt\n  e71000 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_encrypt\n  e71010 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_set_decrypt_key\n  e71050 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_set_encrypt_key\n  e71200 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_BN_bn2le_padded\n  e71240 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_BN_free\n  e71250 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_BN_le2bn\n  e71300 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_BN_new\n
Run Code Online (Sandbox Code Playgroud)\n

这将包含_goboringcrypto_(这意味着应用程序使用boringcrypto而不是本机golang加密)或空输出(这意味着应用程序使用本机golang加密而不是boringcrypto)。

\n

但是,添加时我的应用程序的输出GOEXPERIMENT=boringcrypto是:

\n
\xe2\x9e\x9c  GOEXPERIMENT=boringcrypto CGO_ENABLED=0 go build -o ./bin/app\n\xe2\x9e\x9c  go tool nm bin/dapp | grep -i boring | cat \n 11230a0 T crypto/internal/boring.(*PrivateKeyECDH).PublicKey\n 1123060 T crypto/internal/boring.(*PublicKeyECDH).Bytes\n 243fba0 D crypto/internal/boring..inittask\n 243eda0 D crypto/internal/boring/bbig..inittask\n 1060bc0 T crypto/internal/boring/bcache.registerCache\n 24efe14 B crypto/internal/boring/fipstls.required\n 1123040 T crypto/internal/boring/sig.StandardCrypto.abi0\n 1219c00 T crypto/x509.boringAllowCert\n 24bfae0 B runtime.boringCaches\n\xe2\x9e\x9c  go version bin/app                                                     \nbin/app: go1.20.1 X:boringcrypto\n
Run Code Online (Sandbox Code Playgroud)\n

其中有 0 个匹配项_goboringcrypto_,但有替代项crypto/internal/boring

\n

当我打开crypto/internal/boring\的文档时,我可以看到:

\n
\n

Boring 包提供了对 BoringCrypto 实现函数的访问。检查常量 Enabled 以了解 BoringCrypto 是否可用。如果 BoringCrypto 不可用,这个包中的函数都会崩溃。

\n
\n

基于此,我有两个简单的问题:

\n
    \n
  1. 即使没有匹配项,我的输出在语义上是否等效__goboringcrypto_?换句话说,它是否确认我的应用程序使用boringcrypto而不是本机golang加密货币?
  2. \n
  3. 我正在寻找有关 FIPS 合规性的其他文章,其中一些确实提到了使用CGO_ENABLED=1(但我正在使用CGO_ENABLED=0)。1.20.1使用golang 版本时仍然有要求吗?
  4. \n
\n
\n

Go 1.19 及更高版本:\n从 Go 1.19 开始,您只需添加 [ BUILD_GOEXPERIMENT=boringcrypto][18] 和一些相关参数即可为标准 Go 集成 BoringCrypto。

\n
\n
# Build a binary and assert that it uses boringcrypto instead of the native golang crypto\nRUN GOEXPERIMENT=boringcrypto go build . && \\\n    go tool nm fips-echo-server > tags.txt && \\\n    grep \'_Cfunc__goboringcrypto_\' tags.txt 1> /dev/null\n
Run Code Online (Sandbox Code Playgroud)\n

也就是说,这篇文章

\n
\n

从 go 1.19 开始...在构建时将 GOEXPERIMENT=boringcrypto 传递给 go 工具。就如此容易。

\n
\n

CGO_ENABLED而且根本没有提到flag。

\n

我只能在go 1.18 及更早cgo版本的部分中看到提及:

\n
\n

go 1.18 及更早版本 \n构建必须启用 cgo。

\n
\n

更新

\n
    \n
  1. 我发现另一篇文章暗示CGO_ENABLED=1即使对于 golang 版本 1.19 来说仍然有必要。

    \n
  2. \n
  3. 上一项引用的文章指出goversion

    \n
  4. \n
\n
\n

此外,您还可以使用程序 rsc.io/goversion。当使用 -crypto 标志调用时,它将报告给定二进制文件使用的加密实现。

\n
\n

有这个有趣的PR意味着_Cfunc__goboringcrypto_相当于crypto/internal/boring/sig.BoringCrypto

\n

在此输入图像描述

\n

另请参阅goversion/version/read.go 文件

\n

在此输入图像描述\n在此输入图像描述

\n

也就是说,我的输出有crypto/internal/boring/sig.StandardCrypto且没有crypto/internal/boring/sig.BoringCrypto

\n

我的结论:

\n

总而言之,看起来如果一个应用程序具有以下任何一项:

\n
    \n
  • _Cfunc__goboringcrypto_
  • \n
  • crypto/internal/boring/sig.BoringCrypto
  • \n
\n

在命令的输出中,go tool nm这意味着应用程序使用boringcrypto,并且如果有

\n
    \n
  • crypto/internal/boring/sig.StandardCrypto
  • \n
\n

在其输出中,这意味着应用程序使用本机 golang 加密。

\n

Kos*_*nou 4

全面的,

如果应用程序具有以下任一功能

  • _Cfunc__goboringcrypto_

  • crypto/internal/boring/sig.BoringCrypto

在命令的输出中,go tool nm这意味着应用程序使用boringcrypto并且如果有

  • crypto/internal/boring/sig.StandardCrypto

在其输出中,这意味着应用程序使用本机 golang crypto

具体回答2个问题,

即使 _ goboringcrypto没有匹配项,我的输出在语义上是否等效?换句话说,它是否确认我的应用程序使用boringcrypto而不是本机golang加密货币?

它不是,因为它包含crypto/internal/boring/sig.StandardCrypto而不是_Cfunc__goboringcrypto_/ crypto/internal/boring/sig.BoringCrypto

我正在搜索有关 FIPS 合规性的其他文章,其中一些确实提到使用 CGO_ENABLED=1 (但我正在使用 CGO_ENABLED=0)。使用 1.20.1 版本的 golang 时仍然有要求吗?

这是。

感谢大家的帮助!