区块链安全—随机数安全分析(上)
字数 1291 2025-08-22 12:22:15
区块链安全:随机数安全分析(上)教学文档
一、随机数基础概念
1.1 随机数分类
- 真随机数:通过物理随机过程生成(如骰子、转轮等),难以在计算机中实现
- 伪随机数:
- 强伪随机数:难以预测,常用于密码学
- 弱伪随机数:易于预测
1.2 随机数三大特性
- 随机性:统计学上完全杂乱的数列,分布均匀且独立
- 不可预测性:无法从过去数列推测下一个数
- 不可重现性:除非保存数列本身,否则无法重现相同数列
1.3 随机数特性与分类关系
- 弱伪随机数:只需满足随机性
- 强伪随机数:需满足随机性和不可预测性
- 真随机数:需同时满足三个特性
二、区块链中随机数的特殊挑战
2.1 区块链随机数特点
- 分布式系统要求所有节点能获得相同随机数值
- 需要低延迟生成
- 结果需可验证、可共识
2.2 区块链随机数应用场景
- 抽奖活动
- 验证码
- Token生成
- 密码应用场景(生成密钥、盐值等)
2.3 随机数安全问题
- 随机性生成不应被任何个体控制
- 传统PoS方案使用链上数据(如区块哈希、时间戳)存在安全风险
- 循环论证问题:区块信息由节点写入,又用于选举出块者
- 作恶节点可能操纵随机数生成
三、区块链随机数生成方案
3.1 可信第三方参与生成
实现方式:
- 引入可信第三方为合约提供随机数
- 示例:Oraclize连接random.org获取伪随机数
优缺点:
- 优点:解决节点间随机数一致性问题
- 缺点:
- 违背区块链去中心化理念
- 第三方可信度问题
- 被攻击风险
以太坊实现示例:
pragma solidity ^0.4.11;
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
contract ExampleContract is usingOraclize {
string public ETHUSD;
event LogConstructorInitiated(string nextStep);
event LogPriceUpdated(string price);
event LogNewOraclizeQuery(string description);
function ExampleContract() payable {
LogConstructorInitiated("Constructor was initiated...");
}
function __callback(bytes32 myid, string result) {
if (msg.sender != oraclize_cbAddress()) revert();
ETHUSD = result;
LogPriceUpdated(result);
}
function updatePrice() payable {
if (oraclize_getPrice("URL") > this.balance) {
LogNewOraclizeQuery("Oraclize query was NOT sent...");
} else {
LogNewOraclizeQuery("Oraclize query was sent...");
oraclize_query("URL", "json(https://api.pro.coinbase.com/products/ETH-USD/ticker).price");
}
}
}
3.2 基础合约参与生成(分布式协作)
核心密码学概念:
-
承诺与打开(Commitment & Open):
- 用户先做出选择并计算哈希
- 交换哈希值(承诺)
- 交换实际选择(打开承诺)
- 验证选择与哈希一致
-
秘密共享方案:
- 将秘密拆分为n份分发给n个参与者
- 只需k份(k≤n)即可恢复秘密((k,n)门限方案)
- 示例:直线方程y=ax+b可用于(2,n)共享方案
实现流程:
- 多个参与者协作生成随机数
- 使用区块链记录协议过程
- 对作弊行为进行惩罚(记录在链上)
3.3 公共种子采集生成
实现方式:
- 使用公共区块信息作为随机数种子
- 智能合约根据种子生成伪随机数
安全隐患:
- 一旦攻击者知道算法和种子,可预测随机数
- 常见危险实现示例:
- 使用区块高度:
bool won = (block.number % 2) == 0;
- 使用区块哈希:
pragma solidity ^0.4.18;
contract CoinFlip {
uint256 lastHash;
function get() view public returns(uint256) {
lastHash = uint256(block.blockhash(block.number));
return lastHash;
}
}
- 使用时间戳和难度:
pragma solidity ^0.4.0;
contract random{
function rand() public returns(uint256) {
uint256 random = uint256(keccak256(block.difficulty,now));
return random%10;
}
}
特别警告:
block.blockhash(block.number)总是返回0block.number在执行时是未来区块- 只有交易被打包后,该区块才成为当前区块
四、安全建议
- 避免单独使用区块信息(高度、哈希、时间戳等)作为随机源
- 分布式协作方案更符合区块链理念但实现复杂
- 使用第三方服务需权衡中心化风险
- 任何随机数生成方案都应假设攻击者知道算法
- 对关键应用(如资金相关)的随机数需特别谨慎
五、后续研究方向
- 更安全的分布式随机数生成协议
- 随机数生成中的激励机制设计
- 随机数攻击检测与防御机制
- 不同共识机制下的随机数生成优化
(注:本文档为"区块链安全—随机数安全分析"上篇,下篇将深入分析随机数代码实现、CTF竞赛题目和项目代码案例)