返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

hash 1.18

发布于 2024-10-12 19:15:51 字数 3574 浏览 0 评论 0 收藏 0

散列函数(hash function)又称散列算法、哈希函数,为数据创建 “指纹” 的方法。

散列函数对数据进行计算,获取称作 散列值 (hash code, hash sum)的指纹,这是数据的简单固定摘要。密码学上,散列算法具有 不可逆性 (无法逆向演算回原本的数值)。将数据运算为另一固定长度值,是其基础原理。

基本特性: 如果两个散列值不同(同一函数),那么其原始输入也不相同 。散列函数具有确定性结果,具有这种性质的函数称为单向散列函数。

另一方面,散列函数的输入和输出不是唯一对应关系。如果两个散列值相同,那么两个输入值既可能相同,也可能不同,此种情况称为 “ 散列碰撞 ”(collision)。具备抗碰撞(collision-resistant)的算法虽然安全,但计算量大,速度也比较慢。

散列函数的单向特征,可用来保护数据。比如说,只存储密码哈希值,那么只能验证输入是否正确,而 “无法” 获知原始密码。也可以比对下载的文件摘要,确认是否被篡改。

常见算法:

  • MD5 :消息摘要算法(Message-Digest Algorithm)。

    被广泛使用的密码散列函数。可产生 128 位散列值,确保信息传输完整一致。
    后被证实可破解,不适用于高度安全性资料,建议改用 SHA-2 等。

  • SHA :安全散列算法(Secure Hash Algorithm)。

    散列函数家族,是 FIPS 所认证安全散列算法。计算出数字消息所对应,长度固定的摘要。
    美国国家安全局(NSA)设计,由美国国家标准与技术研究院(NIST)发布,是美国政府标准。

    SHA-1 :广泛用于安全协议(TLS、SSH、 IPsec),是 MD5 后继者。
    SHA-2 :包括 SHA-224、SHA-256、SHA-512 等,目前没有明显弱点。
    SHA-3 :因 MD5 被破解,以及 SHA-1 出现理论破解方法,遂成为替换算法。

  • HMAC :基于散列运算的消息认证码(Hash-based Message Authentication Code)。

    利用散列算法,以密钥和消息为输入,生成消息摘要作输出。
    加入了密钥特征的算法,可作加密、数字签名、报文验证等。

    基于密钥的报文完整性验证方法 ,其安全性是建立在哈希算法基础上的。要求通信双方约定算法、共享密钥,对报文进行运算,形成固定长度认证码。通过认证码校验以确定报文合法性。

    所使用散列函数不限于一种。如用 SHA 家族构造的 HMAC,被称作 HMAC-SHA 等。

  • FNV :非密码学散列函数。

    可快速哈希大量数据并保持较小的冲突概率。
    适合一些相近的数据,如 IP、URL 等。

  • CRC :循环冗余校验(Cyclic Redundancy Check)。

    生成固定位数简短校验码的散列函数,用于检测数据传输和存储时可能出现的错误。
    不能可靠校验数据完整性(即数据没有发生任何变化)。

  • Adler :校验算法。与 CRC 相比,以可靠性换取速度。
// hash

type Hash interface {
	io.Writer

    // return append(b, hashcode)
	Sum(b []byte) []byte

	// Reset resets the Hash to its initial state.
	Reset()

	// Size returns the number of bytes Sum will return.
	Size() int

	// BlockSize returns the hash's underlying block size.
	// The Write method must be able to accept any amount
	// of data, but it may operate more efficiently if all writes
	// are a multiple of the block size.
	BlockSize() int
}

type Hash32 interface {
	Hash
	Sum32() uint32
}

type Hash64 interface {
	Hash
	Sum64() uint64
}

示例

// MD5

package main

import (
	"crypto/md5"
	"fmt"
	"os"
)

func main() {
	b, _ := os.ReadFile("./go.mod")

	h := md5.New()
	h.Write(b)

	fmt.Printf("%x\n", h.Sum(nil))
}
// SHA256

package main

import (
	"crypto/sha256"
	"fmt"
)

func main() {
	h := sha256.New()
	h.Write([]byte("hello, world!"))
	fmt.Printf("%x\n", h.Sum(nil))
}

// 68e656b251e67e8358bef8483ab0d51c6619f3e7a1a9f0e75838d41ff368f728
// CRC32

package main

import (
	"hash/crc32"
	"fmt"
)

func main() {
	h := crc32.NewIEEE()
	h.Write([]byte("hello, world!"))
	fmt.Printf("%x\n", h.Sum32())
}

// 58988d13
// HMAC

package main

import (
	"crypto/sha256"
	"crypto/hmac"
	"fmt"
)

func main() {
	key := []byte("password")
	mac := hmac.New(sha256.New, key)
	mac.Write([]byte("hello, world!"))
	fmt.Printf("%x\n", mac.Sum(nil))
}

// 8202be402d11649fc0a00bfd6d6c3ec2017f486fde252e2b504fdd65ea2a29e8

Online Tools (MD5, SHA256, CRC)

Online HMAC

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文