Go进阶系列

5 Go 密码学(二)哈希

2019-07-08  本文已影响0人  GoFuncChan

一、哈希概述

Hash,音译“哈希”,翻译“散列”。哈希计算就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。这种操作有点类似于数据的“指纹”,任何数据哪怕修改一个Bit也是会产生不同散列值的,这就让消息传输的安全校验有了实现的方法。

哈希计算的特点是:

开发一套高安全性的哈希算法非常困难,业界里一般使用公开的被认证的哈希算法,如md5,sha1,sha256,sha512等,目前md5、sha1已被破解,但还是需要一定代价的,所以现在还在沿用,如果对安全性要求较高,建议使用sha256以上的哈希算法,但对于一些非外部传输的内部校验,还是可以使用md5的,毕竟正向算力成本低。

二、Go 使用哈希加密

Go标准库提供生成消息摘要(指纹)的哈希算法包:

下面我们来演示一下使用示例:

//基本的md5哈希运算
func BaseHash() {
    src := "go func chan"

    //md5计算
    md5 := md5.New()
    md5Bytes := md5.Sum([]byte(src))
    md5String := hex.EncodeToString(md5Bytes)
    fmt.Println("MD5 HASH:", md5String)

    //sha224
    sha224Bytes := sha256.Sum224([]byte(src))
    sha224String := hex.EncodeToString(sha224Bytes[:])
    fmt.Println("SHA224 HASH:", sha224String)

    //sha256
    sha256Bytes := sha256.Sum256([]byte(src))
    sha256String := hex.EncodeToString(sha256Bytes[:])
    fmt.Println("SHA256 HASH:", sha256String)

    //sha384
    sha384Bytes := sha512.Sum384([]byte(src))
    sha384String := hex.EncodeToString(sha384Bytes[:])
    fmt.Println("SHA384 HASH:", sha384String)

    //sha512
    sha512Bytes := sha512.Sum512([]byte(src))
    sha512String := hex.EncodeToString(sha512Bytes[:])
    fmt.Println("SHA512 HASH:", sha512String)

    //OUTPUT:十六进制字符输出
    //MD5 HASH: 676f2066756e63206368616ed41d8cd98f00b204e9800998ecf8427e
    //SHA224 HASH: 5c6ce52ae98e2b27d9aac4d5e4d7b48dfe25fcc11e3f61a8afbeb5ef
    //SHA256 HASH: 69ffe43189a4bc21eca8d70d74786366dd3afcb4a74cdd9c909bf15b538ecac6
    //SHA384 HASH: 4692aa44548c74a5225ce399030039b7c7b5bd963f9c884d5a4810006ab4e3175bc88f27fe3377afab91140ecbd32de8
    //SHA512 HASH: e4c52638805b941dce1d045c5211b307a7486c5e0110c1efe6f627a1b3e7a296d4c5558c10bd015f71c00483770afebc600962cd329aa1565a68231a824cab6c

}

对上述哈希计算分别进行压测得到性能结果的比较:

goos: darwin
goarch: amd64
pkg: cryptography/myHASH
BenchmarkMd5-4           2000000           611 ns/op        1280 B/op          5 allocs/op
--- BENCH: BenchmarkMd5-4
    HashBenchmark_test.go:9: 开始基准测试MD5!!!!
...
BenchmarkSha224-4        2000000           674 ns/op         288 B/op          3 allocs/op
--- BENCH: BenchmarkSha224-4
    HashBenchmark_test.go:19: 开始基准测试Sha224!!!!
...
BenchmarkSha256-4        2000000           676 ns/op         288 B/op          3 allocs/op
--- BENCH: BenchmarkSha256-4
    HashBenchmark_test.go:29: 开始基准测试Sha256!!!!
 ...
BenchmarkSha384-4        2000000           683 ns/op         352 B/op          3 allocs/op
--- BENCH: BenchmarkSha384-4
    HashBenchmark_test.go:39: 开始基准测试Sha384!!!!
...
BenchmarkSha512-4        2000000           721 ns/op         416 B/op          3 allocs/op
--- BENCH: BenchmarkSha512-4
    HashBenchmark_test.go:49: 开始基准测试Sha512!!!!
...
PASS
ok      cryptography/myHASH 10.184s

由上可见其:

性能 : md5>sha224>sha256>sha384>sha512

内存消耗:md5>sha512>sha384>sha256=sha224

相较取舍后,建议平常使用sha256即可,安全性可靠且消耗资源不高。

除了对单个字符串进行哈希,也可分多次添加字符串哈希,下面简单示例:


//多输入源的哈希运算
func MultiSha256(srcs ...string) string {
    hash := sha256.New()

    //往哈希运算器里添加数据
    for _, v := range srcs {
        io.WriteString(hash, v)
    }

    //一般这种方式的参数为nil,因为很少有拼接b哈希运算的情况
    bytes := hash.Sum(nil)
    //十六进制字符串转换输出
    hashString := hex.EncodeToString(bytes)

    return hashString
}
上一篇 下一篇

猜你喜欢

热点阅读