上下文:我正在阅读多篇有关使我的 golang 应用程序符合 FIPS 要求的文章(换句话说,使我的应用程序使用 Boringcrypto 而不是本机 golang crypto):
- https://kupczynski.info/posts/fips-golang/ https://kupczynski.info/posts/fips-golang/
- https://developers.redhat.com/articles/2022/05/31/your-go-application-fips-company# https://developers.redhat.com/articles/2022/05/31/your-go-application-fips-compliant#
简而言之,他们都说要跑
# Build a binary and assert that it uses boringcrypto instead of the native golang crypto
RUN GOEXPERIMENT=boringcrypto go build . && \
go tool nm fips-echo-server > tags.txt && \
grep '_Cfunc__goboringcrypto_' tags.txt 1> /dev/null
然后期望以下输出:
e70fa0 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_cbc_encrypt
e70fc0 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_ctr128_encrypt
e70ff0 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_decrypt
e71000 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_encrypt
e71010 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_set_decrypt_key
e71050 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_AES_set_encrypt_key
e71200 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_BN_bn2le_padded
e71240 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_BN_free
e71250 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_BN_le2bn
e71300 T _cgo_d3bdb93f8e25_Cfunc__goboringcrypto_BN_new
这将包含_goboringcrypto_
(这意味着应用程序使用boringcrypto而不是原生golang加密)或空输出(这意味着应用程序使用原生golang加密而不是boringcrypto)。
但是添加时我的应用程序的输出GOEXPERIMENT=boringcrypto
is:
➜ GOEXPERIMENT=boringcrypto CGO_ENABLED=0 go build -o ./bin/app
➜ go tool nm bin/dapp | grep -i boring | cat
11230a0 T crypto/internal/boring.(*PrivateKeyECDH).PublicKey
1123060 T crypto/internal/boring.(*PublicKeyECDH).Bytes
243fba0 D crypto/internal/boring..inittask
243eda0 D crypto/internal/boring/bbig..inittask
1060bc0 T crypto/internal/boring/bcache.registerCache
24efe14 B crypto/internal/boring/fipstls.required
1123040 T crypto/internal/boring/sig.StandardCrypto.abi0
1219c00 T crypto/x509.boringAllowCert
24bfae0 B runtime.boringCaches
➜ go version bin/app
bin/app: go1.20.1 X:boringcrypto
其中有 0 个匹配项_goboringcrypto_
但有crypto/internal/boring
反而。
当我打开时crypto/internal/boring
's docs https://pkg.go.dev/crypto/internal/boring我能看见:
Boring 包提供了对 BoringCrypto 实现函数的访问。检查常量 Enabled 以了解 BoringCrypto 是否可用。如果 BoringCrypto 不可用,这个包中的函数都会崩溃。
基于此,我有两个简单的问题:
- 即使没有匹配项,我的输出在语义上是否等效
__goboringcrypto_
?换句话说,它是否确认我的应用程序使用boringcrypto而不是本机golang加密货币?
- 我正在寻找有关 FIPS 合规性的其他文章,其中一些确实如此mention https://cs.github.com/sunjayBhatia/contour/blob/d4591c0eed06c19695939aa4004850c5ec0349c6/site/content/guides/fips.md?q=%22GOEXPERIMENT%3Dboringcrypto%22#L50-L59 using
CGO_ENABLED=1
(但是我正在使用CGO_ENABLED=0
)。使用时还是有要求吗1.20.1
golang 版本?
Go 1.19 及更高版本:
从 Go 1.19 开始,您只需添加 [BUILD_GOEXPERIMENT=boringcrypto
][18] 以及一些相关参数,以支持将 BoringCrypto 集成到标准 Go 中。
make container \
BUILD_GOEXPERIMENT=boringcrypto \
BUILD_CGO_ENABLED=1 \
BUILD_EXTRA_GO_LDFLAGS="-linkmode=external -extldflags=-static"
也就是说,本文 https://kupczynski.info/posts/fips-golang/ says
从 go 1.19 开始...在构建时将 GOEXPERIMENT=boringcrypto 传递给 go 工具。就如此容易。
并且没有提到CGO_ENABLED
根本没有标志。
我只能看到提到cgo
在以下部分中转到 1.18 及更早版本:
转到 1.18 及更早版本构建必须启用 cgo。
Updates:
-
I found 另一篇文章 https://projectcontour.io/guides/fips/这意味着有CGO_ENABLED=1
即使对于 golang 版本 1.19 来说仍然是必要的。
-
上一篇文章中引用的文章指出goversion
:
此外,您还可以使用程序 rsc.io/goversion。当使用 -crypto 标志调用时,它将报告给定二进制文件使用的加密实现。
有这个有趣的PR https://github.com/rsc/goversion/pull/21/files这意味着_Cfunc__goboringcrypto_
相当于crypto/internal/boring/sig.BoringCrypto
:
另见goversion/version/read.go
file https://github.com/rsc/goversion/blob/master/version/read.go:
也就是说,我的输出有crypto/internal/boring/sig.StandardCrypto
并不是crypto/internal/boring/sig.BoringCrypto
.
我的结论:
总而言之,看起来如果一个应用程序具有以下任何一项:
_Cfunc__goboringcrypto_
crypto/internal/boring/sig.BoringCrypto
在其输出中go tool nm
命令这意味着应用程序使用boringcrypto,如果有
crypto/internal/boring/sig.StandardCrypto
在其输出中,这意味着应用程序使用本机 golang 加密。