go.sum中特殊hash如何计算
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:base64encodego.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/go-checksum.git
總結
以上是生活随笔為你收集整理的go.sum中特殊hash如何计算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sh256sum、xxd、base64联
- 下一篇: cgo的几种使用方式