Golang为了依赖的安全考虑,在go.mod的基础上引入了go.sum,go.sum文件的作用主要是记录项目依赖的hash值,防止被人修改。
在分析具体项目的go.sum文件后可以发现go.sum中不仅记录了go.mod等的hash值,也记录了整个模块的hash值,这是为什么呢?
这样作的目的主要是在下载整个模块内部的时候可找到子依赖,使得可以并行下载多个依赖。
案例分析
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
# 上面的大致意思是
<module> <version>/go.mod h1:<sha256hash+base64>
# 第一段是模块依赖路径
# 第二段是版本信息/具体文件
# 第三段是针对该文件内容计算的sha256哈希值再进行bash64编码的值
# 其中h1代表的意思就是sha256+base64
复制代码
特殊hash计算
go.mod的特殊hash计算
# 输入:go.mod的文件路径
# 步骤:
# 1.打开go.mod文件读取文件内容进行sha256哈希计算,得到sha256hash
# 2.构建新的字符串 base64in = "sha256hash go.mod\n" ,中间用两个空格分隔,最后必须有一个环行符
# 3.将base64in作为输入给base64进行编码得到base64encode
# 4.字符串拼接得到go.sum中一样的结果 h1:base64encode
复制代码
go.mod的hash计算可以通过shell模拟得出结果,但是对于整个模块的hash计算就无能为力了,下面通过shell命令模拟上述过程
$ sha256sum go.mod
5a93925e1efdeecd8b5755d089fdba6dfb3c04eb85447e8dec8b31cdb44203ab go.mod #sha256hash
$ vim base64in.txt
5a93925e1efdeecd8b5755d089fdba6dfb3c04eb85447e8dec8b31cdb44203ab go.mod # base64in字符串,注意下面的环行符不能少,不然和Golang中的结果对不上
$ sha256sum base64in.txt | xxd -r -ps | base64
+DbmgtsW3Ksw3QccfHlswRDLj07woKf4ku0C0xYA7u0= #base64encode
# 最终的结果经过字符串拼接即可得到 h1:+DbmgtsW3Ksw3QccfHlswRDLj07woKf4ku0C0xYA7u0=
#在写入go.sum时需要同时写上<module> <version>/go.mod h1:+DbmgtsW3Ksw3QccfHlswRDLj07woKf4ku0C0xYA7u0=
复制代码
整个模块的特殊hash计算
对整个模块进行hash计算时不是直接对打包好的zip包求hash,而是对解压后的文件进行遍历hash计算后再进行一次总的hash计算,这样作的目的是避免因为zip算法进行打包时由于字节的差异导致对整个zip包的hash结果不一致
# 输入:模块所在目录和模块在的导入路径(在源码中使用时的那个导入路径)
# 步骤:
# 1. 遍历模块中所有文件
# 只考虑文件,不考虑目录
# 忽略.git目录内的所有文件
# 拼接每个文件相对路径与导入路径到一起
# 例如:导入路径 "github.com/spf13/cobra",该包中command.go文件经过拼接后为:github.com/spf13/cobra/command.go
# 将遍历的结果存储在一个列表中方便后面计算hash
# 2. 对上一步得到的列表进行排序 (排序主是保证hash结果一致)
# 3.然后进行遍历hash,其计算过程是在排序后的列表中读取一个文件进行sha256 hash 将"ha256hash github.com/spf13/cobra/command.go\n"字符串拼接在后一个文件hash结果前面,以此类推最后得到一个所有文件hash结果的字符串
# 4.对上面的长字符串再进行sha256 hash计算得到结果sha256hash进行base64编码得到base64encode
# 5.在写入go.sum时类似如下:
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
# 第一行是对整个包的hash结果
# 第二行是对go.mod的hash结果
复制代码
上面的过程都可以在Golang源码中找到,在github找到了一位大神也对这种特殊的hash进行了复现:hub.fastgit.org/vikyd/go-ch…
标签:文件,hash,sum,计算,go,mod From: https://www.cnblogs.com/acodedreamer/p/17116208.html