Golang为了依赖的平安思考,在go.mod的根底上引入了go.sum,go.sum文件的作用次要是记录我的项目依赖的hash值,避免被人批改。
在剖析具体我的项目的go.sum文件后能够发现go.sum中不仅记录了go.mod等的hash值,也记录了整个模块的hash值,这是为什么呢?
这样作的目标次要是在下载整个模块外部的时候可找到子依赖,使得能够并行下载多个依赖。
起初我认为go.sum中记录的hash值是通过sha256间接计算再进行base64编码后的后果,然而在实际操作验证时失去的base64值和go.sum中记录的总是对不上,因而通过查看go的源码(/usr/local/go/src/cmd/go/上面对/usr/local/go/src/cmd/vendor/golang.org/x/mod/sumdb/dirhash包下有援用依赖,这里也是实现go.sum的底层算法外围)发现Golang对文件的hash和整个我的项目的hash计算并不是简略的sha256计算和base64编码。
案例剖析
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进行了复现:https://hub.fastgit.org/vikyd...