
前言
前言
前言
知道創宇區塊鏈安全實驗室將對此進行詳細解讀。
一級標題
一級標題
一級標題
Web-interface 與IPFS
1. Web-interface 是什麼
2. IPFS 是什麼
1.永久的、去中心化保存和共享文件
星際文件系統(IPFS)是分佈式存儲和共享文件的網絡傳輸協議,它將現有的成功系統分佈式哈希表、版本控制系統Git、BitTorrent、自認證文件系統與區塊鏈相結合。正是這些系統的綜合優勢,給IPFS 帶來了以下顯著特性:
1.永久的、去中心化保存和共享文件
2.點對點超媒體:P2P 保存各種各樣類型的數據
3.版本化:可追溯文件修改歷史
4.內容可尋址:通過文件內容生成獨立哈希值來標識文件,而不是通過文件保存位置來標識https://ipfs.io當用戶將文件添加到IPFS 時,該文件會被拆分為更小的塊,經過加密哈希處理並賦予內容標識符CID 作為唯一指紋;當其他節點查找該文件時,節點會詢問對等節點誰存儲了該文件CID 引用的內容,當查看、下載這份文件時,他們將緩存一份副本——同時成為該內容的另一個提供者,直到他們的緩存被清除。
IPFS使用實例
網站
提供一個帶UI 界面的客戶端,安裝運行後會啟動IPFS 的服務,顯示當前的節點ID、網關和API 地址:
我們導入想上傳的文件,上傳文件成功後會生成該文件的CID 信息,通過QmHash(CID)我們也能查找到指定的文件:
IPFS中的傳統安全問題https://IPFS.io以
根據使用實例,我們知道IPFS 允許上傳任意類型的文件,由於允許Web 訪問下載文件的特性,導致攻擊者可以像傳統安全一樣使用HTML 或SVG 文件實現釣魚:
以
網關為例,上傳一個Metamask 釣魚網站,由於存儲在受信域名里,受害者訪問該文件很可能攻擊成功:
`CID::=
但由於IPFS 只能通過CID 查詢文件,使得釣魚攻擊的利用面很窄,沒辦法定向的實施攻擊。既然CID 是發起定向攻擊的關鍵,那我們回頭研究下CID。
package main
import (
"fmt"
mc "github.com/multiformats/go-multicodec"
mh "github.com/multiformats/go-multihash"
cid "github.com/ipfs/go-cid"
)
const (
File = "./go.sum"
)
func main() {
pref := cid.Prefix{
Version: 0,
Codec: mc.Raw,
MhType: mh.Base58,
MhLength: -1,
}
c, err := pref.Sum([]byte("CIDTest"))
if err != nil {...}
fmt.Println("CID: ", c)
}
IPLD 是構建IPFS 的數據層,它定義了默克爾鏈接(Merkle-Links)、默克爾有向無環圖(Merkle-DAG) 和默克爾路徑(Merkle-Paths)三種數據類型,通過IPLD 發送到IPFS的數據保存在鏈上,使用者會收到一個CID 來訪問該數據。
type AddEvent struct {
Name string
Hash string `json:",omitempty"`
Bytes int64 `json:",omitempty"`
Size string `json:",omitempty"`
}
const (
quietOptionName = "quiet"
quieterOptionName = "quieter"
silentOptionName = "silent"
progressOptionName = "progress"
trickleOptionName = "trickle"
wrapOptionName = "wrap-with-directory"
onlyHashOptionName = "only-hash"
chunkerOptionName = "chunker"
pinOptionName = "pin"
rawLeavesOptionName = "raw-leaves"
noCopyOptionName = "nocopy"
fstoreCacheOptionName = "fscache"
cidVersionOptionName = "cid-version"
hashOptionName = "hash"
inlineOptionName = "inline"
inlineLimitOptionName = "inline-limit"
)
CID 是一個由Version、Codec和Multihash 三部分組成的字符串,目前分成V0和V1兩個版本。 V0 版採用Base58 編碼生成CID,V1 版包含表明內容的編號種類Codec、哈希算法MhType 和哈希長度MhLength 共同構成:
func (adder *Adder) AddAllAndPin(ctx context.Context, file files.Node) (ipld.Node, error) {
ctx, span := tracing.Span(ctx, "CoreUnix.Adder", "AddAllAndPin")
defer span.End()
我們以go-cid 生成一組CID 測試:
adder.unlocker = adder.gcLocker.PinLock(ctx)
}
defer func() {
if adder.unlocker != nil {
adder.unlocker.Unlock(ctx)
}
}()
if err := adder.addFileNode(ctx, "", file, true); err != nil {
return nil, err
}
mr, err := adder.mfsRoot()
if err != nil {
return nil, err
}
var root mfs.FSNode
可以看到在生成CID 的過程中,無法實現結果的預測和更換,我們再往上分析上傳文件的部分。將文件上傳到IPFS,通過塊的方式保存到本地blockstore 的過程位於/go-ipfs-master/core/commands/add.go:
root = rootdir
err = root.Flush()
if err != nil {
return nil, err
}
_, dir := file.(files.Directory)
var name string
if !dir {
children,把上傳文件信息保存到AddEvent 對像中,再通過/go-ipfs-master/core/coreunix/add.go 裡的addALLAndPin 和fileAdder.AddFile 方法遍歷文件路徑,讀取文件內容,將數據送入塊中:
if err != nil {
return nil, err
}
if len(children) == 0 {
return nil, fmt.Errorf("expected at least one child dir, got none")
}
name = children[0]
root, err = rootdir.Child(name)
if err != nil {
return nil, err
}
}
err = mr.Close()
if err != nil {
return nil, err
}
nd, err := root.GetNode()
if err != nil {
return nil, err
}
err = adder.outputDirs(name, root)
if err != nil {
return nil, err
}
if asyncDagService, ok := adder.dagService.(syncer); ok {
err = asyncDagService.Sync()
if err != nil {
return nil, err
}
}
if !adder.Pin {
return nd, nil
}
return nd, adder.PinRoot(ctx, nd)
}
if adder.Pin {//knownsec 如果被鎖定
func (adder *Adder) addFile(path string, file files.File) error {
var reader io.Reader = file
if adder.Progress {
rdr := &progressReader{file: reader, path: path,rootdir := mr.GetDirectory()//knownsec 獲取路徑
if fi, ok := file.(files.FileInfo); ok {
reader = &progressReader2{rdr, fi}
} else {
reader = rdr
}
}
dagnode,err := rootdir.ListNames(adder.ctx)//knownsec 展示當前路徑文件名
if err != nil {
return err
}
return adder.addNode(dagnode, path)
}
分析代碼發現,IPFS 在打包文件上傳返回CID 的整個過程,都沒實現劫持的可能,而成功上傳的文件無法實現修改其內容,同樣無法實現篡改:
後記
後記