交易延展性与隔离见证SegWit
交易延展性问题的原理和漏洞
交易延展性 是比特币中存在的一种设计缺陷,指的是攻击者可以通过修改交易的某些部分(通常是签名)而不影响交易的有效性,从而改变交易 ID(交易哈希)。这可能导致链上某些依赖交易 ID 的逻辑失效,甚至被用来发动攻击。
具体攻击场景
1. 普通场景中交易延展性的问题
- Alice 向 Bob 发起了一笔比特币交易(假设金额是 1 BTC),交易的输入和输出已经签名并广播到网络。
- 在交易被矿工打包到区块之前,Bob 拦截了这笔交易并通过以下方式修改了交易:
- 不改变交易的主要内容(如输入和输出)。
- 修改了签名的某些非关键部分(如签名格式或编码方式)。
- 修改后的交易仍然是有效的,但由于签名的改变,交易的哈希值(即交易 ID)也随之变化。
结果:
- Bob 将修改后的交易广播到网络并被矿工接受,最终上链。
- Alice 发现交易 ID 已经改变,如果 Alice 的程序依赖于原来的交易 ID,则可能误以为这笔交易没有成功。
2. 攻击者利用交易延展性的案例
双重花费攻击
- 假设 Alice 发起一笔交易,将 1 BTC 发送到 Bob 的地址,并要求 Bob 提供某种服务或商品。
- Alice 可以在交易广播后,利用交易延展性修改交易的签名,从而生成一个不同的交易 ID。
- 修改后的交易被矿工打包上链,而原始交易被丢弃。
- 如果 Bob 的系统依赖于原始交易 ID 来确认支付,则会认为 Alice 并没有支付,从而服务或商品可能未交付。
闪电网络或复杂协议中的问题
- 在闪电网络或链下协议中,交易 ID 通常用于标识链上交易。如果交易 ID 被篡改,可能导致支付通道或智能合约状态出现错误,甚至被利用进行资金窃取。
SegWit 如何解决交易延展性问题
SegWit 通过将签名数据从交易的主体部分中分离到一个独立的“见证(witness)”部分,从根本上解决了交易延展性问题。
1. 分离见证数据
- 在 SegWit 中,交易的哈希值(交易 ID)只基于交易的“非见证数据”部分计算。
- “见证数据”部分,包括签名和脚本数据,不再影响交易的哈希值。
原始交易结构:
[版本号][输入][输出][签名]
SegWit 中的交易结构:
[版本号][输入][输出][见证哈希]
2. 原理
- 因为攻击者只能篡改签名(见证部分),但签名不影响交易的哈希值,任何修改都无法改变交易 ID。
- 攻击者再也不能通过交易延展性问题生成新的交易 ID,交易 ID 的唯一性得以保证。
具体例子:修复交易延展性
未修复的情形
- Alice 发起交易,将 1 BTC 转给 Bob。
- Alice 生成的交易 ID 是:
txid1 = HASH(版本号 || 输入 || 输出 || 签名)
- Bob 拦截后修改签名,生成新的交易 ID:
txid2 = HASH(版本号 || 输入 || 输出 || 修改后的签名)
- Bob 广播 txid2,txid1 被丢弃。
SegWit 修复后
- Alice 发起交易,交易结构变为:
txid = HASH(版本号 || 输入 || 输出) witness_hash = HASH(见证数据)
- Bob 即使篡改了见证数据,影响的只是
witness_hash
,但txid
不会发生变化。 - 交易 ID 保持不变,Alice 和 Bob 的系统不会受到篡改的影响。
SegWit 的安全性改进总结
- 彻底修复交易延展性:分离签名数据使得交易 ID 不受签名修改的影响。
- 提高协议可靠性:修复交易延展性问题为闪电网络等依赖链上交易 ID 的协议铺平了道路。
- 增强防护能力:减少了双重花费攻击和其他依赖交易延展性的问题的可能性。
SegWit 是比特币历史上重要的升级之一,从根本上解决了困扰多年的技术缺陷,并为未来扩展奠定了基础。
修改后的签名仍满足比特币网络签名校验规则
Bob 修改后的签名仍然需要满足比特币网络验证签名的规则,否则交易会被视为无效而被拒绝。接下来我们分步解释为什么 Bob 可以修改签名,以及修改签名如何仍然保持有效:
1. 签名的可变性
比特币的签名使用的是 ECDSA(椭圆曲线数字签名算法),这种算法本身具有某些特性,使得签名在特定情况下可以被调整而不改变其有效性。主要的签名可变性来源如下:
(1)r
和 s
值的可选性
- 一个 ECDSA 签名由两个部分组成:
(r, s)
。 - 签名中
s
值有两种表示方式:- 正常形式:
s
本身。 - 低
s
形式:s' = n - s
(n
是椭圆曲线的阶)。
- 正常形式:
- 比特币网络在 SegWit 之前没有强制要求低
s
表示,因此攻击者可以通过将s
修改为等效的另一种形式,从而生成新的签名。
(2)额外字节的填充
- 签名通常以 DER 编码格式存储。
- 攻击者可以在 DER 编码中添加无意义的填充字节(例如前导零),不会改变签名的有效性,但会改变其二进制表示。
2. Bob 如何修改签名
假设 Alice 构造了如下交易:
- 输入(Input):引用一个未花费输出(UTXO)。
- 输出(Output):转账金额和目标地址。
- 签名:Alice 对交易的哈希进行签名,生成
(r, s)
。
攻击步骤
- Bob 获取 Alice 广播的交易,提取其中的签名。
- Bob 修改签名的表示形式,例如:
- 将签名中的
s
替换为等效的s' = n - s
。 - 修改 DER 编码格式,增加无意义的填充。
- 将签名中的
- Bob 替换原始交易中的签名部分,生成一个新的交易。
- Bob 将修改后的交易广播到比特币网络。
由于修改后的签名仍然满足 ECDSA 签名验证规则(哈希值对应相同的公钥),网络节点会接受这笔交易。
3. SegWit 如何解决这个问题
SegWit 通过将签名数据分离到见证部分,并且将交易 ID 的计算仅依赖于交易的非见证部分,解决了这个问题。
- 非见证部分:包括输入、输出等基本信息。
- 见证部分:包含签名数据。
- 在 SegWit 中,攻击者即使修改签名,只会改变见证部分的哈希值(
witness_hash
),不会改变交易 ID(txid
)。
此外,SegWit 强制采用了 低 s
规则,从编码层面减少了签名的可变性,使得攻击更难实现。
4. 总结
在交易延展性问题中,Bob 利用的是比特币早期签名规则的灵活性,通过修改签名的编码或使用等效的 s
值生成新交易。但这种修改只能改变交易的哈希值,而不会影响交易的有效性。
SegWit 的出现通过以下方式解决了这一问题:
- 将签名数据移到见证部分,使交易 ID 的计算不受签名影响。
- 强制低
s
规则,彻底消除签名可变性。 - 降低复杂协议(如闪电网络)对交易延展性的依赖,提升了系统安全性和可靠性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
2022-01-21 2022年技术书单
2022-01-21 【转】云原生体系概述
2020-01-21 java线程池与tomcat线程池策略算法上的异同
2017-01-21 三菱蓝瑟改装记录