密码学基础:哈希函数原理、SHA-256算法、非对称加密(公钥/私钥)、数字签名
大家好,我是你们的老朋友。今天咱们来聊聊区块链的“地基”——密码学。说实话,没有密码学,区块链就是个笑话。我当年刚入行时,觉得这玩意儿就是一堆数学公式,枯燥得很。后来在做一个NFT交易平台时,因为签名验证的细节没处理好,差点导致用户资产被盗……嗯,从那以后,我再也不敢小看密码学了。
这一章,我会把哈希函数、SHA-256、非对称加密和数字签名这几个核心概念,用我自己的理解讲给你听。保证不堆砌公式,但该有的深度一点不少。
1. 哈希函数:区块链的“指纹”
哈希函数,说白了就是一个“压缩+映射”的过程。你给它任意长度的数据,它都能给你一个固定长度的输出。这个输出,我们叫它“哈希值”或“摘要”。
我个人习惯把哈希函数想象成一个“碎纸机+打印机”的组合。你把文件塞进去,它碎成粉末,然后根据粉末的图案,打印出一张固定大小的纸条。只要文件有一点点不同,打印出来的纸条就完全不一样。
哈希函数有几个关键特性,我列出来给你看:
- 单向性:从哈希值反推原始数据,几乎不可能。我试过暴力破解一个SHA-256的哈希值,跑了三天三夜,毛都没捞着。
- 抗碰撞性:找到两个不同数据,但哈希值相同,几乎不可能。理论上存在,但现实中你碰不到。
- 雪崩效应:输入改一个比特,输出就天翻地覆。你试试把“hello”改成“Hello”,哈希值完全不一样。
- 固定输出长度:不管输入是1KB还是1GB,输出长度都一样。比如SHA-256,永远是256位。
重要概念:哈希函数不是加密。加密可以解密,哈希不行。哈希是“摘要”,不是“密文”。
2. SHA-256:比特币的“心脏”
SHA-256,全称是“安全哈希算法-256位”。它是SHA-2家族的一员,也是比特币和大多数区块链系统的主力哈希算法。
我记得第一次看SHA-256的算法细节时,头都大了。一堆位运算、循环移位、模加……后来我明白了,你不需要记住每一步,只需要知道它“怎么保证安全”就行。
SHA-256的核心流程,我简化成几个步骤:
- 填充:把原始数据补到512位的整数倍。最后64位存原始长度。
- 分块:每512位一个块,依次处理。
- 扩展:每个块扩展成64个32位字。
- 压缩:用64轮循环,把当前块和中间结果混合。
- 输出:最后得到8个32位字,拼起来就是256位的哈希值。
你可能会问:“为什么要搞这么复杂?” 原因很简单——为了抗碰撞。每一轮都引入了非线性操作,让攻击者找不到规律。
我的小技巧:在项目中,如果你需要快速验证哈希值,可以用命令行:echo -n "hello" | sha256sum。Linux和macOS都支持。
3. 非对称加密:公钥和私钥的“双钥匙”系统
非对称加密,是区块链里最巧妙的设计之一。它不像传统加密那样用同一把钥匙,而是用一对钥匙:公钥和私钥。
公钥,你可以公开给全世界。私钥,你必须死死藏好,谁都不能给。这两把钥匙的关系是:
- 用公钥加密的数据,只能用私钥解密。
- 用私钥加密的数据,只能用公钥解密。
你想想看,这多方便。别人想给你发加密消息,直接用你的公钥加密。你收到后,用私钥解密。全程不需要交换密钥。
在区块链里,最常见的非对称加密算法是椭圆曲线加密(ECC),特别是secp256k1曲线。比特币和以太坊都在用。
为什么选椭圆曲线?因为它比RSA更“省”。同样安全强度下,ECC的密钥更短,计算更快。我做过测试,同样256位的安全级别,RSA需要3072位密钥,而ECC只需要256位。差距一目了然。
避坑指南:我曾经见过一个项目,直接把私钥硬编码在代码里。结果代码被反编译,私钥泄露,整个链上的资产全被盗了。记住:私钥永远不要出现在代码、日志、网络传输中。
4. 数字签名:区块链的“电子印章”
数字签名,是非对称加密的“反向应用”。你不是要加密数据,而是要证明“这个数据是我发的”。
流程很简单:
- 发送方用私钥对数据的哈希值进行“签名”。
- 接收方用发送方的公钥验证签名。
为什么是对哈希值签名,而不是对原始数据?因为原始数据可能很大,签名计算很慢。哈希一下,变成固定长度,再签名,效率高得多。
数字签名保证了三点:
- 身份认证:只有持有私钥的人才能生成有效签名。
- 不可否认:签名者无法否认自己签过名。
- 完整性:数据一旦被篡改,签名验证就会失败。
在区块链交易中,每一笔交易都包含一个数字签名。矿工验证签名通过后,才把交易打包进区块。如果签名不对,交易直接丢弃。
核心要点:数字签名 ≠ 加密。签名是“证明身份”,加密是“保护内容”。两者用的都是非对称加密,但目的完全不同。
5. 实战:用Python演示签名与验证
光说不练假把式。我写一段简单的Python代码,用椭圆曲线演示签名和验证。你可以在自己的机器上跑跑看。
# 需要安装 ecdsa 库:pip install ecdsa
import ecdsa
import hashlib
# 生成私钥和公钥
private_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
public_key = private_key.get_verifying_key()
# 要签名的消息
message = b"Hello, Blockchain!"
# 对消息的哈希值签名
signature = private_key.sign(message, hashfunc=hashlib.sha256)
# 验证签名
try:
public_key.verify(signature, message, hashfunc=hashlib.sha256)
print("签名验证成功!")
except ecdsa.BadSignatureError:
print("签名验证失败!")
# 篡改消息后验证
fake_message = b"Hello, Blockchain?"
try:
public_key.verify(signature, fake_message, hashfunc=hashlib.sha256)
print("签名验证成功!")
except ecdsa.BadSignatureError:
print("签名验证失败!—— 消息被篡改")
运行结果:第一段输出“签名验证成功!”,第二段输出“签名验证失败!—— 消息被篡改”。
你看,只要消息改了一个字符,签名就失效了。这就是数字签名的威力。
6. 总结与思考
这一章的内容,是区块链安全的基石。哈希函数保证数据完整性,非对称加密保证通信安全,数字签名保证身份可信。三者缺一不可。
我个人建议,你在学习后续章节时,随时回头看看这一章。因为后面讲的共识机制、智能合约、NFT元数据验证,全都建立在密码学之上。
最后留个思考题:如果有一天量子计算机成熟了,现有的SHA-256和椭圆曲线加密还能用吗?嗯,这个问题,我们后面会专门讲。
推荐阅读:如果你想深入,可以看看《Mastering Bitcoin》的密码学章节。或者直接读NIST的SHA-256标准文档。虽然枯燥,但绝对权威。
好了,这一章就到这里。下一章,我们聊聊“区块链的数据结构:区块、链、默克尔树”。到时候见。