第二章:密码学基础

第二章:密码学基础

密码学是区块链技术的基石。本章将深入探讨支撑区块链安全性的核心密码学概念,包括哈希函数、公钥密码学、数字签名等关键技术。

本章目标:

  • 理解密码学在区块链中的核心作用
  • 掌握哈希函数的特性和应用
  • 学习公钥/私钥加密机制
  • 了解数字签名的工作原理
  • 探索 Merkle 树等高级密码学结构

2.1 密码学简介

密码学(Cryptography)是研究如何在敌对环境中安全通信的科学。在区块链中,密码学提供了以下关键功能:

密码学的核心目标

  1. 机密性(Confidentiality)

    • 确保信息只能被授权方读取
    • 防止未授权访问
  2. 完整性(Integrity)

    • 检测数据是否被篡改
    • 确保数据未被修改
  3. 认证性(Authentication)

    • 验证通信方的身份
    • 确认消息来源
  4. 不可否认性(Non-repudiation)

    • 发送方无法否认发送过某条消息
    • 提供行为证据

区块链中的密码学应用

哈希函数 区块链接 工作量证明 地址生成 非对称加密 账户系统 交易签名 身份验证 数字签名 交易授权 多重签名 消息认证 Merkle树 数据验证 轻节点 状态证明

2.2 哈希函数

什么是哈希函数?

哈希函数(Hash Function)是一种将任意长度的输入数据映射为固定长度输出的单向函数。

哈希函数的关键特性

  1. 确定性(Deterministic)

    • 相同输入总是产生相同输出
    • 可重现和验证
  2. 快速计算(Fast Computation)

    • 能够快速计算哈希值
    • 高效的验证过程
  3. 单向性(One-way)

    • 从哈希值无法反推原始数据
    • 抗原像攻击(Pre-image Resistance)
  4. 雪崩效应(Avalanche Effect)

    • 输入微小变化导致输出巨大变化
    • 增强安全性
  5. 抗碰撞性(Collision Resistance)

    • 极难找到两个不同输入产生相同输出
    • 防止伪造攻击

SHA-256 算法

SHA-256(Secure Hash Algorithm 256-bit)是比特币使用的主要哈希算法。

SHA-256 特点

  • 输出长度:256 位(32 字节)
  • 通常表示为 64 位十六进制字符
  • 计算速度快,安全性高

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// SHA-256 哈希示例
const crypto = require('crypto');

function sha256(data) {
return crypto.createHash('sha256')
.update(data)
.digest('hex');
}

// 示例 1:普通文本
console.log(sha256('Hello, Blockchain!'));
// 输出: 7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069

// 示例 2:微小变化导致完全不同的哈希
console.log(sha256('Hello, blockchain!')); // 注意小写 b
// 输出: 93a0f1d4f8e8e8c4... (完全不同)

哈希在区块链中的应用

1. 区块链接

区块 N-1 区块 N 区块 N+1

2. 工作量证明(PoW)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 简化的 PoW 示例
function proofOfWork(blockData, difficulty) {
let nonce = 0;
const target = '0'.repeat(difficulty);

while (true) {
const hash = sha256(blockData + nonce);

if (hash.startsWith(target)) {
return { nonce, hash };
}

nonce++;
}
}

// 查找以 4 个 0 开头的哈希
const result = proofOfWork('Block Data', 4);
console.log(`Found: ${result.hash} with nonce ${result.nonce}`);
// 输出: Found: 0000a3f2... with nonce 157392

3. 地址生成

公钥 SHA-256 RIPEMD -160 Base58 Check 地址

其他重要哈希算法

RIPEMD-160

  • 输出:160 位(20 字节)
  • 用途:比特币地址生成
  • 特点:更短的输出,节省空间

Keccak-256

  • 用于:以太坊
  • 输出:256 位
  • 特点:SHA-3 的变体

Blake2

  • 用于:某些新兴区块链
  • 特点:比 SHA-256 更快
  • 安全性:与 SHA-3 相当

2.3 对称加密与非对称加密

对称加密(Symmetric Encryption)

使用相同密钥进行加密和解密。

工作原理

发送方 接收方 共享密钥 K 加密(M, K) 密文 C 解密(C, K) 发送方 接收方

常见对称加密算法

  • AES(Advanced Encryption Standard)

    • 最广泛使用
    • 支持 128、192、256 位密钥
  • DES/3DES

    • 较老的标准
    • 已不推荐使用

优缺点

优点:

  • ✅ 加密速度快
  • ✅ 适合大量数据
  • ✅ 计算资源消耗少

缺点:

  • ❌ 密钥分发困难
  • ❌ 密钥管理复杂
  • ❌ 不适合公开网络

非对称加密(Asymmetric Encryption)

使用一对密钥:公钥(Public Key)和私钥(Private Key)。

核心概念

密钥对生成 公钥 可公开 私钥 保密 数学关联 单向

加密通信流程

Alice Bob 公钥 pk_Bob 加密(M, pk_Bob) 密文 C 解密(C, sk_Bob) Alice Bob

常见非对称加密算法

1. RSA

  • 基于大数分解难题
  • 密钥长度:2048-4096 位
  • 用途:TLS/SSL、数字签名
1
2
3
4
5
6
7
8
9
// RSA 概念示例(简化)
// 密钥生成
const { publicKey, privateKey } = generateRSAKeyPair();

// 加密
const encrypted = rsaEncrypt(message, publicKey);

// 解密
const decrypted = rsaDecrypt(encrypted, privateKey);

2. ECC(椭圆曲线加密)

  • 基于椭圆曲线离散对数问题
  • 密钥长度:256 位(相当于 RSA 3072 位安全性)
  • 优势:更短的密钥,更高效

区块链常用曲线:

  • secp256k1:比特币、以太坊使用
  • Ed25519:Solana、Polkadot 使用
  • secp256r1:某些企业区块链

ECC 工作原理

椭圆曲线 y²=x³+ax+b secp256k1 y²=x³+7 点加法 P+Q=R 私钥 随机256位 公钥 pk=sk×G

示例:以太坊密钥对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 以太坊密钥对生成示例
const { randomBytes } = require('crypto');
const secp256k1 = require('secp256k1');

// 1. 生成私钥(256 位随机数)
let privateKey;
do {
privateKey = randomBytes(32);
} while (!secp256k1.privateKeyVerify(privateKey));

console.log('私钥:', privateKey.toString('hex'));
// 输出: 7c4e8... (64位十六进制 = 32字节 = 256位)

// 2. 从私钥派生公钥
const publicKey = secp256k1.publicKeyCreate(privateKey, false);
console.log('公钥:', publicKey.toString('hex'));
// 输出: 04b8a... (130位十六进制 = 65字节,未压缩格式)

// 3. 生成以太坊地址(公钥的 Keccak-256 哈希的后20字节)
const keccak256 = require('keccak256');
const address = keccak256(publicKey.slice(1)).slice(-20).toString('hex');
console.log('地址: 0x' + address);
// 输出: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0

对称 vs 非对称加密对比

特性 对称加密 非对称加密
密钥 单一密钥 公钥 + 私钥
速度 慢(10-1000倍)
密钥分发 困难 容易
用途 大数据加密 密钥交换、签名
示例 AES, DES RSA, ECC
区块链应用 钱包加密 交易签名

2.4 数字签名

数字签名是使用私钥对数据进行签名,任何人都可以用对应的公钥验证签名的真实性。

数字签名的作用

  1. 身份认证:证明消息确实来自私钥持有者
  2. 数据完整性:证明消息未被篡改
  3. 不可否认:签名者无法否认签过名

数字签名工作流程

消息 M Hash 签名 sk 签名 σ 验证 pk ✅ 有效 ❌ 无效

ECDSA(椭圆曲线数字签名算法)

比特币和以太坊使用的签名算法。

签名生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 以太坊交易签名示例
const secp256k1 = require('secp256k1');
const keccak256 = require('keccak256');

// 交易数据
const txData = {
nonce: 0,
gasPrice: '20000000000',
gasLimit: '21000',
to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
value: '1000000000000000000', // 1 ETH
data: '0x'
};

// 1. 序列化交易数据(RLP 编码)
const serialized = rlpEncode(txData);

// 2. 计算哈希
const txHash = keccak256(serialized);

// 3. 使用私钥签名
const { signature, recid } = secp256k1.ecdsaSign(txHash, privateKey);

// 4. 签名结果
const r = signature.slice(0, 32);
const s = signature.slice(32, 64);
const v = recid + 27; // 以太坊的 v 值

console.log('签名 - r:', r.toString('hex'));
console.log('签名 - s:', s.toString('hex'));
console.log('签名 - v:', v);

签名验证

1
2
3
4
5
6
7
8
// 验证签名
function verifySignature(txHash, signature, publicKey) {
return secp256k1.ecdsaVerify(signature, txHash, publicKey);
}

// 使用
const isValid = verifySignature(txHash, signature, publicKey);
console.log('签名有效:', isValid); // true

比特币交易签名

构建交易 序列化 双SHA-256 ECDSA签名 完整交易

多重签名(MultiSig)

需要多个私钥共同签名才能完成交易。

M-of-N 多签

2-of-3 多签 Alice Bob Charlie 交易 签名 A 签名 B ✅ 有效

比特币 P2SH 多签脚本

1
2
3
4
5
# 2-of-3 多签脚本
OP_2
<公钥A> <公钥B> <公钥C>
OP_3
OP_CHECKMULTISIG

2.5 Merkle 树

Merkle 树(Merkle Tree),也称哈希树,是一种树形数据结构,用于高效验证大量数据的完整性。

Merkle 树结构

Merkle Root Hash 0-1 Hash 2-3 Hash 0 Hash 1 Hash 2 Hash 3 Tx 0 Tx 1 Tx 2 Tx 3

构建 Merkle 树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// Merkle 树实现示例
const crypto = require('crypto');

class MerkleTree {
constructor(leaves) {
this.leaves = leaves.map(l => this.hash(l));
this.root = this.buildTree(this.leaves);
}

hash(data) {
return crypto.createHash('sha256')
.update(data)
.digest('hex');
}

buildTree(nodes) {
if (nodes.length === 1) {
return nodes[0];
}

const parents = [];

for (let i = 0; i < nodes.length; i += 2) {
const left = nodes[i];
const right = nodes[i + 1] || nodes[i]; // 奇数个节点时复制最后一个

const parent = this.hash(left + right);
parents.push(parent);
}

return this.buildTree(parents);
}

getRoot() {
return this.root;
}
}

// 使用示例
const transactions = ['tx1', 'tx2', 'tx3', 'tx4'];
const tree = new MerkleTree(transactions);
console.log('Merkle Root:', tree.getRoot());

Merkle 证明(Merkle Proof)

轻量级验证,无需下载全部数据。

Hash 3 Hash 0-1 Hash Tx 2 Hash 2-3 计算Root 比较 ✅ 存在 ❌ 不存在

Merkle 证明代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class MerkleTree {
// ... 前面的代码 ...

// 生成 Merkle 证明
getProof(leaf) {
let index = this.leaves.indexOf(this.hash(leaf));
if (index === -1) return null;

const proof = [];
let nodes = this.leaves;

while (nodes.length > 1) {
const parents = [];

for (let i = 0; i < nodes.length; i += 2) {
const left = nodes[i];
const right = nodes[i + 1] || nodes[i];

if (i === index || i === index - 1) {
// 记录兄弟节点
const sibling = (i === index) ? right : left;
const position = (i === index) ? 'right' : 'left';
proof.push({ hash: sibling, position });
index = Math.floor(index / 2);
}

parents.push(this.hash(left + right));
}

nodes = parents;
}

return proof;
}

// 验证 Merkle 证明
verifyProof(leaf, proof, root) {
let hash = this.hash(leaf);

for (const { hash: siblingHash, position } of proof) {
if (position === 'left') {
hash = this.hash(siblingHash + hash);
} else {
hash = this.hash(hash + siblingHash);
}
}

return hash === root;
}
}

// 使用示例
const tree = new MerkleTree(['tx1', 'tx2', 'tx3', 'tx4']);
const proof = tree.getProof('tx2');
const isValid = tree.verifyProof('tx2', proof, tree.getRoot());

console.log('Merkle Proof:', proof);
console.log('验证结果:', isValid); // true

Merkle 树的应用

1. 比特币区块结构

Version Previous Hash Merkle Root Timestamp Difficulty Nonce Transactions

2. SPV 轻节点

SPV(Simplified Payment Verification) 节点只需下载区块头,不需要下载全部交易。

全节点 ~500GB 完全验证 轻节点 ~100MB Merkle证明

3. 状态树(State Tree)

以太坊使用 Merkle Patricia Trie 存储账户状态。

状态树 账户状态 交易树 交易数据 收据树 交易收据

2.6 高级密码学概念

零知识证明(Zero-Knowledge Proof)

零知识证明允许证明者向验证者证明某个陈述是真的,而不透露任何额外信息。

经典例子:阿里巴巴洞穴

Alice随机进入 Bob随机要求 Alice从指定 边出来 知道密码 100%成功 不知道 概率1/2^N

zk-SNARKs

zk-SNARKs(Zero-Knowledge Succinct Non-Interactive Argument of Knowledge)

应用:

  • Zcash:隐私交易
  • Tornado Cash:以太坊混币
  • zkSync:Layer 2 扩容
简洁 ~200字节 非交互 Setup Prove Verify

同态加密(Homomorphic Encryption)

同态加密允许对密文直接进行计算,解密后得到对明文计算的结果。

传统: E(a)+E(b)≠E(a+b) 同态: E(a)⊕E(b)=E(a+b) 隐私计算

门限签名(Threshold Signature)

多方共同持有私钥的分片,需要 t-of-n 个分片才能生成有效签名。

分片1 分片2 分片3 任意3个 合成签名 分片4 分片5 ≤2个 无法签名

本章小结

导航:

0%