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
은 해시 패키지에서 제공하는 해시 함수로 바로 해싱을 한 모습입니다.#2
는 hash.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