blog-go-crypto/hash at main · vompressor/blog-go-crypto
Contribute to vompressor/blog-go-crypto development by creating an account on GitHub.
코드

go 는 다양한 해시 함수를 지원합니다.

MD4          // import golang.org/x/crypto/md4
MD5          // import crypto/md5
SHA1         // import crypto/sha1
SHA224       // import crypto/sha256
SHA256       // import crypto/sha256
SHA384       // import crypto/sha512
SHA512       // import crypto/sha512
RIPEMD160    // import golang.org/x/crypto/ripemd160
SHA3_224     // import golang.org/x/crypto/sha3
SHA3_256     // import golang.org/x/crypto/sha3
SHA3_384     // import golang.org/x/crypto/sha3
SHA3_512     // import golang.org/x/crypto/sha3
SHA512_224   // import crypto/sha512
SHA512_256   // import crypto/sha512
BLAKE2s_256  // import golang.org/x/crypto/blake2s
BLAKE2b_256  // import golang.org/x/crypto/blake2b
BLAKE2b_384  // import golang.org/x/crypto/blake2b
BLAKE2b_512  // import golang.org/x/crypto/blake2b

다음처럼 해시 함수를 얻습니다.

package main

import (
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"

	"golang.org/x/crypto/blake2b"
	"golang.org/x/crypto/ripemd160"
	"golang.org/x/crypto/sha3"
)

func main() {
	md5.New()
	sha256.New()
	sha3.New256()
	ripemd160.New()
	sha1.New()
	sha512.New512_256()
	// ...
}

이러한 함수들은 hash.Hash 인터페이스를 리턴합니다.

type Hash interface {
	// 해싱할 데이터를 입력합니다.
    // Write(b []byte) (int, error)
	io.Writer

	// 입력한 데이터를 해싱합니다.
    // b의 값 + 입력한 데이터의 해시를 리턴합니다.
    // 해시만 얻고자 하면, b의 값을 nil로 입력합니다.
	Sum(b []byte) []byte

	// 해시를 초기화 합니다.
	Reset()

	// 해시 사이즈를 리턴합니다.
	Size() int

	// 해시의 기본 블록 크기를 리턴합니다.
    // Write 메서드는 데이터 길이에 관계없이 입력할 수 있지만,
    // Write의 입력이 블록 크기의 배수인 경우
    // 더 효율적으로 작동됩니다.
	BlockSize() int
}

SHA256 예시

package main

import (
	"crypto/sha256"
	"fmt"
)

func main() {
	// #1 데이터를 바로 해시
	h1 := sha256.Sum256([]byte("hello world"))

	// #2 여러 데이터를 해시
	hasher := sha256.New()
	hasher.Write([]byte("hello "))
	hasher.Write([]byte("world"))
	h2 := hasher.Sum(nil)

	// #3 해시 체이닝
	hasher1 := sha256.New()
	h3 := make([]byte, 0)

	// 'hello ' 해싱
	hasher1.Write([]byte("hello "))
    
    // h3(nil) + 'hello ' 해시 리턴
	h3 = hasher1.Sum(h3)
	hasher1.Write([]byte("world"))
    
    // h3(hashed 'hello ') + 'hello world' 리턴
	h3 = hasher1.Sum(h3)

	fmt.Printf("1: %x\n", h1)
	fmt.Printf("2: %x\n", h2)
	fmt.Printf("3: %x\n", h3)
}
// 출력
1: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
2: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
3: 5e3235a8346e5a4585f8c58562f5052b8fe26a3bb122e1e96c76784964dfc461b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

/* #3 구조
'hello ' hashed
5e3235a8346e5a4585f8c58562f5052b8fe26a3bb122e1e96c76784964dfc461

'hello world' hashed
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
*/

#1 은 해시 패키지에서 제공하는 해시 함수로 바로 해싱을 한 모습입니다.
#2hash.Hash 인터페이스를 통해 해싱을 하였습니다.

#3 는 조금 복잡합니다.

Hash.Sum(b []byte) 함수는 hasher 에 입력된 값을 해싱하여 슬라이스 b 뒤에 붙여서 리턴 합니다.

Hash.Sum() 을 호출한다고 기존에 입력된 값들이 없어지지 않습니다. hasher를 초기화하려면 Hash.Reset() 함수를 호출해야 합니다.

package main

import (
	"crypto/sha256"
	"fmt"
)

func main() {
	// hasher 생성
	hasher := sha256.New()

	// 'hello ' 입력
	hasher.Write([]byte("hello "))
	// 입력된 값 해싱
	h := hasher.Sum(nil)

	// 'world' 입력
	hasher.Write([]byte("world"))
	// 입력된 값 해싱, 위에 입력한 'hello '도 같이 해싱됨
	w1 := hasher.Sum(nil)

	// hasher에 입력된 값 제거
	hasher.Reset()
	// 'world' 입력
	hasher.Write([]byte("world"))
	// 입력한값 해싱
	w2 := hasher.Sum(nil)

	// hasher에 입력된 값 제거
	hasher.Reset()
	// 'world' 입력
	hasher.Write([]byte("hello world"))
	// 입력한값 해싱
	w3 := hasher.Sum(nil)

	fmt.Printf("'hello ' hashed :\n%x\n", h)
	fmt.Printf("'world' hashed :\n%x\n", w1)
	fmt.Printf("hasher reseted, 'world' hashed :\n%x\n", w2)
	fmt.Printf("hasher reseted, 'hello world' hashed :\n%x\n", w3)
}
// 출력
'hello ' hashed :
5e3235a8346e5a4585f8c58562f5052b8fe26a3bb122e1e96c76784964dfc461
'world' hashed :
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
hasher reseted, 'world' hashed :
486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7
hasher reseted, 'hello world' hashed :
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9