
머리말
머리말
통신 기술은 세상을 더 연결하게 만들었고 우리 각자는 그러한 연결로 인해 영향을 받고 혜택을 받습니다. 동시에 이 연결은 모니터링 요구에 더 많은 편의를 제공합니다. 많은 사람들의 개인 정보 또는 자유가 부주의하게 손상될 수 있으며 이로 인해 개인 정보 보호가 필요합니다. 일반적으로 중앙 집중식 서버의 존재로 인해 완전한 개인 정보 보호를 달성하기는 어렵지만 분산 스토리지와 같은 기술을 통해 가능합니다.
Chuangyu Blockchain Security Lab에서 이에 대해 자세히 설명해 드릴 것을 알고 있습니다.
첫 번째 레벨 제목
웹 인터페이스 및 IPFS
1. 웹 인터페이스란?
Web3.0에서 분산 퍼블릭 체인 기술 시설은 사용자가 호출할 수 있는 다양한 인터페이스를 제공하지만 이러한 인터페이스는 일반 사용자가 직접 사용할 수 없습니다. 사용자에게 웹 인터페이스는 사용자와 웹 서버에서 실행되는 소프트웨어 사이의 다리입니다. 사용자는 브라우저를 사용하여 표시 및 상호 작용을 위해 웹 인터페이스에 연결하고 동시에 지갑을 통해 자신을 식별합니다. 기본 블록체인 인프라의 경우 웹 인터페이스는 사용자가 직접 사용할 수 있는 친숙한 페이지에 패키지된 퍼블릭 체인/스마트 계약의 캡슐화 계층입니다. 구조와 기능은 다음 그림과 유사합니다.
2. IPFS란?
IPFS(Interplanetary File System)는 분산 저장 및 공유 파일을 위한 네트워크 전송 프로토콜로 기존의 성공적인 시스템 분산 해시 테이블, 버전 제어 시스템 Git, BitTorrent, 자체 인증 파일 시스템 및 블록체인을 결합합니다. IPFS에 다음과 같은 주목할만한 기능을 제공하는 것은 이러한 시스템의 포괄적인 이점입니다.
1. 영구적이고 분산된 파일 저장 및 공유
2. P2P 하이퍼미디어: P2P는 다양한 형태의 데이터 저장
3. 버전 관리: 추적 가능한 파일 수정 내역
4. 콘텐츠 주소 지정 가능: 파일이 저장된 위치가 아닌 파일 콘텐츠에서 독립적인 해시 값을 생성하여 파일을 식별합니다.
사용자가 IPFS에 파일을 추가하면 파일은 더 작은 청크로 분할되고 암호학적으로 해시되며 고유한 지문으로 콘텐츠 식별자(CID)가 부여됩니다. 파일의 CID에 의해 파일을 보고 다운로드할 때 캐시된 복사본을 갖게 되며 캐시가 지워질 때까지 해당 콘텐츠의 다른 공급자가 됩니다.
IPFS 사용 예https://ipfs.io웹사이트
클라이언트에 UI 인터페이스 제공 설치 및 운영 후 IPFS 서비스가 시작되고 현재 노드 ID, 게이트웨이 및 API 주소가 표시됩니다.
업로드할 파일을 가져옵니다. 파일을 성공적으로 업로드하면 파일의 CID 정보가 생성됩니다. 또한 QmHash(CID)를 통해 지정된 파일을 찾을 수 있습니다.
IPFS는 분산 저장 및 공유 파일을 위한 네트워크 전송 프로토콜이므로 성공적으로 업로드된 파일이 다른 노드에 복사된 후 로컬 노드가 적극적으로 파일을 삭제하더라도 IPFS 네트워크에서 파일을 계속 쿼리할 수 있습니다.
IPFS의 기존 보안 문제
사용 예에 따르면 IPFS는 모든 유형의 파일 업로드를 허용한다는 것을 알고 있습니다.웹 액세스를 허용하여 파일을 다운로드할 수 있는 기능으로 인해 공격자는 HTML 또는 SVG 파일을 사용하여 기존 보안과 마찬가지로 피싱을 수행할 수 있습니다.https://IPFS.io~에 의해
게이트웨이를 예로 들어 메타마스크 피싱 웹사이트를 업로드하고 파일이 신뢰할 수 있는 도메인 이름에 저장되기 때문에 피해자가 파일에 액세스할 때 공격이 성공할 가능성이 높습니다.
그러나 IPFS는 CID를 통해서만 파일을 쿼리할 수 있기 때문에 피싱 공격의 사용 범위가 매우 좁고 표적 공격을 수행할 방법이 없습니다. CID는 표적 공격을 시작하는 핵심이므로 CID를 다시 살펴보겠습니다.
IPLD는 IPFS 구축을 위한 데이터 계층으로 Merkle-Links, Merkle-DAG 및 Merkle-Paths의 세 가지 데이터 유형을 정의합니다.IPLD에서 IPFS로 보낸 데이터는 체인에 저장되며 사용자는 CID를 받아 액세스할 수 있습니다. 데이터.
`CID::=
CID는 Version, Codec, Multihash로 구성된 문자열로 현재 V0과 V1의 두 가지 버전으로 나뉩니다. V0 버전은 Base58 인코딩을 사용하여 CID를 생성하고 V1 버전은 콘텐츠를 나타내는 숫자 유형 코덱, 해시 알고리즘 MhType 및 해시 길이 MhLength를 포함합니다.
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)
}
go-cid를 사용하여 일련의 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를 생성하는 과정에서 결과의 예측 및 대체가 불가능함을 알 수 있는데, 파일을 업로드하는 부분을 분석해 보자. 파일을 IPFS에 업로드하고 블록을 통해 로컬 블록스토어에 저장하는 프로세스는 /go-ipfs-master/core/commands/add.go에 있습니다.
func (adder *Adder) AddAllAndPin(ctx context.Context, file files.Node) (ipld.Node, error) {
ctx, span := tracing.Span(ctx, "CoreUnix.Adder", "AddAllAndPin")
defer span.End()
업로드된 파일 정보를 AddEvent 개체에 저장한 다음 /go-ipfs-master/core/coreunix/add.go의 addALLAndPin 및 fileAdder.AddFile 메서드를 통해 파일 경로를 탐색하고 파일 내용을 읽고 데이터를 다음으로 보냅니다. 블록:
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
if adder.Pin {//knownsec 잠긴 경우
root = rootdir
err = root.Flush()
if err != nil {
return nil, err
}
_, dir := file.(files.Directory)
var name string
if !dir {
children,rootdir := mr.GetDirectory()//knownsec 경로 가져오기
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)
}
err := rootdir.ListNames(adder.ctx)//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,마지막으로 addFile 함수를 사용하여 파일을 업로드합니다.
if fi, ok := file.(files.FileInfo); ok {
reader = &progressReader2{rdr, fi}
} else {
reader = rdr
}
}
dagnode,out: adder.Out}//knonwsec 바이트 단위로 파일 읽기
if err != nil {
return err
}
return adder.addNode(dagnode, path)
}
코드를 분석한 결과, IPFS는 패키징된 파일의 CID를 업로드하고 반환하는 전 과정에서 하이재킹 가능성이 없으며, 성공적으로 업로드된 파일은 수정하거나 변조할 수 없습니다.
추신
추신