Published
- 36 min read
深入剖析加密货币中的签名机制

非对称加密基础与数字签名概念
加密货币的安全基础源于非对称加密(公钥加密)技术,即每个人拥有一对密钥:公开的公钥和保密的私钥。公钥可以公开用于加密或验证,私钥则必须由拥有者秘密保存,用于解密或签名等操作。
所谓数字签名,指的就是使用私钥对一段数据计算出的一个只有发送者才能产生、他人无法伪造的数字串,用于证明消息的来源和完整性。
简单来说,数字签名的作用类似现实中的签字盖章,但它通过数学算法实现,能够确保签名对应的信息未被篡改且确实来自签名者本人。
数字签名的工作原理
为帮助理解,我们来看一个基本例子:Alice 想给 Bob 发一条重要消息并确保 Bob 确信消息来自她且中途未被修改。Alice 会先对消息计算哈希值,然后用她的私钥对该哈希值进行加密运算生成数字签名;接着将原始消息和数字签名一起发送给 Bob。
Bob 收到后,用 Alice 的公钥对数字签名进行验证,同时自己计算消息的哈希并进行比对。如果验证通过且哈希一致,就说明消息完整无误,确实是由掌握对应私钥的 Alice 发出的。
整个过程无需泄露私钥,Bob 仅凭公钥就完成了真实性校验。这种基于非对称加密的签名机制,确保了消息:
- 不可伪造:他人无法产生对应的有效签名
- 不可抵赖:签名者事后无法否认消息是其签发
这是密码学保障信任的核心手段。
签名在加密货币中的核心作用
在区块链和加密货币中,数字签名扮演着至关重要的角色,每一笔比特币的转移都通过数字签名来进行确认:拥有者用私钥对上一笔交易和下一拥有者的公钥哈希签名,把币转移给下一所有者,收款方通过验证这个签名链来确认币的所有权。
也就是说,签名就是数字货币所有权转移的凭证:只有拥有某币对应私钥的人才能生成有效签名花费该币,从而确保”币”不可被他人冒用或双花。
具体而言,加密货币利用数字签名来证明交易发起者对所用资金的控制权,同时保护私钥不被暴露。每当用户要花费自己的加密货币时,就需要对交易细节用私钥生成签名;网络中的节点和接收方则使用用户公布的公钥来验证签名,以此确认交易确实由资金拥有者授权,而交易数据在传输过程中没有被篡改。
数字签名的两大核心作用
- 证明交易中引用的资产(如比特币的UTXO或以太坊账户余额)确实属于发起交易的用户
- 保证交易的所有数据都是由该用户提供且未被修改,即交易的完整性和真实性
这样,区块链系统无需第三方中介,仅凭密码学签名就能建立信任:一笔交易上的签名既充当了对所有权的证明,也确保了交易过程中的防篡改。这正是加密货币体系去信任化(trustless)的基石——依靠数学而非人工来保障参与方的权益。
比特币中的签名机制及应用
在比特币系统中,数字签名主要体现在交易的构建和验证过程中。比特币采用UTXO模型,每笔交易消耗之前的未花费输出,并产生新的输出。为了证明自己有权花费某个UTXO,交易的发起者(付款人)必须在交易中提供对该UTXO的数字签名。
比特币交易结构
一笔比特币交易主要由 输入(Input) 和 输出(Output) 两部分构成:
- 每个输入引用一笔先前交易的输出(即UTXO)并提供一个解锁脚本 scriptSig,其中包含付款人对本次交易的签名和付款人的公钥,用于解锁所引用的UTXO
- 每个输出则包含转账的比特币数量和一个锁定脚本 scriptPubKey,规定了将来解锁该输出所需的条件(通常是收款人的公钥哈希及相关脚本指令)
简而言之,输入脚本提供”证明”,输出脚本规定”条件”,只有提供了符合条件的签名,先前UTXO里的币才能被花费。
签名生成与验证流程
在构建交易时,钱包软件会收集需要花费的UTXO,并准备好新的交易内容(包括输入引用、输出地址和金额等)。然后,它会使用相关UTXO所属的私钥对交易数据进行数字签名。具体的签名生成步骤如下:
-
交易哈希计算:将准备好的交易消息(包括输入输出等字段)进行哈希运算(比特币中通常对交易数据做双SHA-256哈希),得到固定长度的散列值
-
生成签名:使用拥有该UTXO的私钥,对上述消息散列值运行椭圆曲线数字签名算法(ECDSA,secp256k1曲线)计算出签名结果。签名由两个大数构成,通常记作 (r, s)。此签名将唯一对应该交易消息和私钥,任何他人无法伪造
生成签名后,钱包会将签名和公钥一并填入交易输入的scriptSig中。例如,用户B花费之前A转给他的比特币时,B在交易输入里提供 <sig_B><PubK(B)>
作为解锁脚本,证明自己对先前UTXO的支配权。完成所有输入的签名后,一笔完整的交易就构建成功,可以广播到比特币网络等待验证了。
注意,签名是完全可以离线操作,你在本地签名好之后,代表你已经构建了一个比特币的交易,只不过其他节点还不知道。这个时候你需要通过 广播 Broadcast 来把交易发送去区块链上,其他的区块链节点才能获取到这笔交易。而以太坊用户,则很少会做离线的操作,大部分的钱包交互都是直接和链进行的交互。
签名验证机制
当交易传播到网络中的矿工和节点后,会进入签名验证阶段。比特币脚本系统会将输入的解锁脚本和之前输出的锁定脚本组合执行,以检查签名的有效性。
对于标准的支付交易(P2PKH):
- 首先,解锁脚本提供的公钥通过哈希160计算与锁定脚本中的公钥哈希进行比对,验证该UTXO确实属于当前提供签名的用户
- 接着,OP_CHECKSIG 操作会提取解锁脚本中的签名和公钥,对交易内容计算哈希并使用公钥进行ECDSA验证
如果验证结果为真,则表明签名正确,即交易确由对应私钥持有者创建且期间未被篡改;若验证失败,交易即被判定无效,不会被网络接受。通过这种机制,比特币确保了只有合法签名的交易才能修改账本状态,实现了去中心化的资产控制和防欺诈。
需要注意,比特币的签名通常对交易的大部分信息进行了覆盖(默认情况下签名类型为SIGHASH_ALL,即签名涵盖几乎交易的所有字段),从而防止交易广播后被恶意篡改关键内容。比特币最初使用ECDSA签名算法,后来在Taproot升级中引入了更高效的Schnorr签名方案,但签名的核心作用不变:证明拥有权和保护交易完整性。
总之,在比特币体系中,没有数字签名的交易无法得到网络承认——签名机制是点对点电子现金系统正常运转的必要条件。
以太坊中的签名机制与”签名 vs 授权”
以太坊同样依赖数字签名来保障交易安全,但其账户模型和签名使用上有一些区别。以太坊采用账户模型(Account Model),每个外部账户(EOA)由一对公私钥控制。任何一笔以太坊链上的交易都必须由发起账户的私钥签名,否则网络不会执行。
签名包含在交易的数据结构中(以太坊交易由RLP编码后附加签名域),具体包括 (r, s, v) 三个参数,其中 r 和 s 是ECDSA签名值,v 是恢复标志,用于帮助从签名中恢复出公钥。验证时,以太坊节点通过 (r,s,v) 从签名中推导出发送方的公钥和地址,并比对该地址是否与交易中的 from 字段一致,从而确认交易确实由账户所有者签发。
这个机制使得以太坊无需在交易中直接包含公钥就能验证签名,提高了效率(比特币则是在脚本中携带公钥进行验证)。
签名与授权的区别
值得深入讨论的是”签名”和”授权”在以太坊中的区别。在钱包使用中,很多用户会遇到既要”签名”(Sign)又要”授权”(Approve/Confirm)的情况,二者含义有所不同却又紧密相关。
签名(Signature)
泛指用户在钱包中用私钥对任意数据进行的签署操作,作用相当于”我同意此内容”的确认。链上交互的各个环节几乎都需要用户签名——无论是简单的身份证明(登录DApp)、转账交易,还是与智能合约的互动操作,最终都要通过用户签名来获得授权后才能执行。换言之,在钱包里出现的”Sign”或”Confirm”提示,本质都是在请求用户用私钥签名授权某项操作或数据。一旦用户签名,意味着他认可了相应操作,可以理解为在数字合同上签了字。
授权(Approve/Permit 等)
狭义上特指给予某个合约特定权限的操作,例如批准一个DApp合约可以代替自己花费一定数量的代币。授权其实是签名的一种特殊用途,可以称作”带授权的签名”。常见的例子是ERC-20代币的 Approve:用户执行Approve交易,允许某合约日后花费自己一定额度的代币。这属于链上交易,需要支付Gas,并在区块链状态中记录授权额度。当用户在钱包中点击”确认授权”时,实际上就是签名并发送了一笔包含授权指令的交易。
需要注意的是,“授权”原本是为提升使用体验而设计,让用户无需每次都签署新交易就能让合约代为操作资产。但授权本身一定要有用户签名才能生效。因此可以说授权是签名的一个子集:所有的授权行为都涉及签名,但并非每个签名都是在做授权(有的签名只是一次性操作,并不赋予持久权限)。
实际应用场景
用一个简单的场景区别签名和授权:当我们使用去中心化交易所(如Uniswap)交换代币时,首先网站会要求”连接钱包”,此时弹出的请求一般是让用户签名一段消息以证明”我是这个钱包的拥有者”,这只是链下操作,不涉及任何资产移动,也无需Gas费用。完成登录签名后,当你真正发起交换比如用100 USDT兑换代币时,合约需要得到你的授权才能扣除你的USDT。这时你会执行一个授权交易(Approve),花费少量Gas链上提交,内容是”我批准Uniswap合约可以从我的账户支取100枚USDT”。授权确认后,再发起交换交易将USDT换成目标代币。但是现在新型的DEX也会免去Approve这一步,直接把Approve这个需要消耗gas的操作通过Permit2这种离线签名的方式来实现,用户在兑换代币的时候就只需支付一次消耗gas费的操作。
可见,签名更多是在链下确认身份或同意某个消息,授权则通常是一种改变链上权限状态的操作(允许某合约动用你的资产),通常需要上链。
签名风险认知:用户为何常忽视签名危险?
尽管签名在加密交易中至关重要,但许多普通用户并未充分认识到签名操作本身潜在的风险。过去不少人误以为:“只要我没主动发送交易上链,只是在钱包里点了签名确认,是不会丢失资产的。“这种观念在早期相对单一的场景下似乎没出过大问题,但随着签名用途的扩展,这种掉以轻心正在酿成严重后果。
用户对签名风险的误解
习惯性麻痹
不少用户养成了”见签名弹窗就立即确认”的习惯。在上一轮牛市中,几乎每个DApp都要求用户连接钱包并签名以登录,久而久之大家默认这种离线签名是安全的、不会有实质损失。尤其是这些签名不消耗Gas、一签即可登录,多数情况下内容只是证明地址所有权,对用户来说习以为常。因此用户心理上对签名的警惕性远低于对链上交易的警惕——毕竟交易要花钱还会修改资产状态,而签名看起来什么都没发生。
信息展示不佳
很多钱包在展示签名内容时的可读性不佳,加剧了用户的漫不经心。例如,理想情况下签名的信息应当清晰告知用户将要签署的数据。但早期的 eth_sign 签名请求往往直接显示一串十六进制字符串(俗称”盲签”),用户完全看不懂自己在签什么。即使后来有了EIP-712这种改进的结构化数据签名标准,可以让钱包界面显示更人性化的内容,依然有项目方为了图方便不按规范来,或者用户自己不加以留意。
正如安全社区所指出的:“如果用户从不阅读签名内容,哪怕再详细清晰也无济于事”。因此,不少黑客会利用伪装签名请求的方式行骗——例如把恶意交易构造成看似无害的登录签名,让用户在不知情的情况下签下足以盗走其资产的”许可条款”。
签名钓鱼事件频发
这种缺乏安全意识的现象直接导致了签名钓鱼事件频发。根据安全机构统计,在2024年3月的钓鱼事件中,90%被盗资产都是ERC-20代币,而主要手段正是利用Permit/Permit2签名进行钓鱼。很多受害者直到资产被转移后还以为自己的私钥泄露,最后才发现原来是曾经随手签过的一个离线签名造成授权失控。
归根结底,这一切本可以避免——只要用户把签名看成和转账交易一样严肃的操作,三思而后行。正如某些科普文章所比喻的那样:签名就像在一张纸上签署允许他人动用你资产的字条,哪怕当下不扣钱,也可能日后被人拿去兑现。一旦用户意识到”签名可能会带来资产变动”的危险,本能上就会更慎重,而不是遇到弹窗不加分辨地乱点”确认”。
风险认知总结
概括来说,用户忽视签名风险的原因在于:
- 习惯使然的麻痹:将所有签名操作都视作例行公事
- 信息不对称:钱包展示不友好导致用户不理解签名内容
- 新型签名授权兴起:在不了解新机制的情况下,用旧思维认为签名无害
提高安全意识需要时间和教育,但黑客不会停止利用这一漏洞。在下文中,我们将列举以太坊生态中与签名相关的几类敏感操作,分析其中的风险,希望加深大家对签名威力和危险性的认识。
总之,在以太坊里签名无处不在:不仅发送交易需要签名,很多DApp的高级功能(如订单签名、消息签名登录)都用到签名。而授权是特定意义上的签名,用于赋权某合约/地址,可以看作”带有后续效力的签名”。理解二者关系有助于用户辨别钱包弹窗提示——当钱包请求你签名时,需要弄清这是否涉及授权某项资产或权限,从而判断风险。
签名引发的危险操作分析(EIP-2612、EIP-712、EIP-7702 等)
随着以太坊功能的丰富,数字签名已不仅用于简单的转账确认,还能触发各种复杂操作。如果不加防范,用户一次看似普通的签名可能赋予他人巨大的权限,导致资产受损。下面我们结合几项重要的以太坊改进提案(EIP),来看签名究竟可以完成哪些敏感操作,以及其中暗藏的风险。
EIP-2612:Permit 签名授权
EIP-2612引入了一种方便用户授予ERC-20代币使用权限的方式——Permit,允许用户通过离线签名来授权代币转移,而无需先发送链上Approve交易。
举例来说,在传统流程中,如果Alice想授权某合约花费她的代币,需要签名并发送一笔 approve 交易给链上合约,付Gas费并等待打包。而有了Permit,Alice只需在钱包里签署一条消息(内容包含代币合约、授权额度、期限等),然后将签名交给对方,对方就能拿着这个签名去链上调用 permit 函数,直接获得Alice代币的使用权。从链上看,等效于Alice预先批准了代币转移,但整个授权过程Alice自己没出一分钱,也没有主动广播交易——这一切都隐藏在她签下的那串数字签名里。
Permit极大地方便了用户(尤其在需要频繁授权的DeFi场景),但也滋生了新的攻击手法。黑客如果诱骗用户签署了恶意的Permit消息,就相当于拿到了一张可以随时支配用户代币的支票!攻击者往往会部署一个钓鱼合约,请用户签名一个Permit授权,比如伪装成领取空投的网站让你”登录”。一旦你签了名,攻击者随后即可调用代币合约的 transferFrom,把你的代币转走。
更可怕的是,这种盗取往往发生在你毫无察觉的时刻——攻击者甚至可以等待几天,等你遗忘此事或等代币升值后再下手。而Permit2(Uniswap推出的改进版授权协议)则进一步扩大了风险:它允许黑客一次获取你钱包中所有代币的授权权限,只要你进行了相关签名。
事实上,近期多起DeFi钓鱼案中,大量受害者的ERC-20代币被莫名其妙转走,追查后发现元凶就是之前某次粗心的签名授权。因此,Permit签名是一把双刃剑:用得好减少了繁琐操作,用不好则给了黑客可乘之机。
用户务必要对任何请求Permit/授权签名的行为提高警惕,确认签名内容(钱包如MetaMask通常会针对Permit弹出警告或特别提示)。
EIP-712:结构化数据签名(Typed Data)
EIP-712规定了一种签名格式,使签名的数据结构对用户是可阅读的。它的初衷是减少”盲签”风险,让钱包在签名确认界面上直观展示待签名的数据字段。
例如,在使用去中心化交易所或NFT市场时,用户经常需要签名离线订单(如挂单卖出NFT,签名订单后由买家撮合成交)。通过EIP-712,钱包可以显示诸如订单类型、代币ID、价格、到期时间等信息字段,用户据此更容易判断自己签的是什么。相比之下,老式的 eth_sign 只显示原始字符串,用户几乎无法获知签名意图。
然而,EIP-712本身并不能杜绝签名被滥用。它只是提供了更友好的信息呈现,最终起作用的还是用户是否真正去看、去理解这些内容。如果用户一味”秒签”,那么哪怕提示再清晰也可能掉进陷阱。例如,今年曾发生过某知名项目Galxe的钓鱼事件,签名内容里的交易细节其实是明文写出的,但许多用户没有仔细核对就签了,结果资产被转走。
可见,EIP-712提高了安全上限,但并不改变”签名=授权”的本质。在技术层面,EIP-712签名被大量用于DeFi和NFT领域的敏感操作:如去中心化交易所的离线撮合订单签名、跨链桥消息签名、DAO治理投票签名等等。这些签名往往涉及对资产的处置或权利的转移。
例如,用户在OpenSea签名一条出售NFT的订单,一旦签名生成并被买方执行,等于授权市场合约可在符合条件时转走你的NFT完成交易;又如用户给某DAO提案签名投票,实际上是授权计票合约记录你的决策。一旦签名出手,就具备了法律合同般的效力,由智能合约自动执行。
因此对待EIP-712类型的签名,用户也需谨慎对待——虽然钱包界面更友好,但务必确认每个字段是否符合自己意图,防止被别有用心者利用签名达成非本人意愿的操作。
EIP-7702:账户抽象的签名”变身”
这是以太坊社区最近热议的一项提案,旨在赋予普通外部账户(EOA)类似智能合约账户的能力,并将其视作实现全面账户抽象(Account Abstraction)的”终极方案”之一。
EIP-7702提出了一种新的交易类型,允许交易中包含一个特殊字段 contract_code,节点在执行交易时会临时将签名者账户附上一段合约代码,使其在该笔交易期间具备智能合约的行为能力。交易执行完毕后,节点再将账户的合约代码字段清空,恢复为普通EOA。
这一过程完全由签名授权触发:用户需要对交易进行签名,其中包含一个”授权元组”详细说明了 contract_code 的内容及其执行条件。也就是说,用户通过签名明确同意在此交易中将这段特定代码附加到自己的账户上并执行。节点会验证签名和授权列表,确认无误后才会在交易处理时注入并运行该合约代码。
EIP-7702的出现使得”签名可以临时改变账户行为”成为可能。例如,过去只有智能合约钱包才能实现的批量转账、一次交易执行多个操作、Gas费代付等高级功能,现在普通EOA用户只要对一笔包含相应 contract_code 的交易签名,就能享受类似功能。
这对于改善用户体验有巨大好处——想象一下,你可以签名一笔交易,让你的账户临时具备多重签名钱包的安全逻辑,或者批量完成几十笔转账而只花一笔Gas。
然而,从安全角度看,这也意味着签名的威力更上一层楼:你的签名不仅可以花你的钱,还可以”变造”你的账户行为(虽是暂时的)。如果有黑客设计出恶意的 contract_code 并诱骗你签名授权,那么在那一次交易里,你的账户可能执行任意对攻击者有利的操作。
虽然EIP-7702规定了执行结束后代码会自动移除,降低了永久控制的风险,“临时授权”本身仍需非常小心使用。此前类似的账户抽象提案EIP-3074曾引发讨论:它允许EOA签名授权某合约代理自己执行操作,一旦授权给恶意合约,攻击者即可利用你的身份转走你钱包里所有资产。
EIP-7702在技术上避免了引入永久授权(通过一次性合约代码注入替代持续委托),并兼容了现有智能钱包逻辑,但最终做决定的那一下签名仍在用户手中。未来账户抽象功能越强大,用户签名时需要考虑的后果就越复杂:你的签名可能不只是简单转账,而是触发一系列复杂合约调用。
对于这些新型签名操作,生态也在探索相应的安全措施,例如钱包提供合约代码白名单或模拟执行预警,以保护用户不误签恶意代码。可以预见,随着EIP-7702等方案的推进,数字签名将可以驱动更敏感更强大的操作,我们也必须同步提升风险防范意识。
总结
数字签名贯穿了加密货币世界的一切操作,小到登录认证、大到资产转移甚至账户行为改造,都可以通过一串签名来实现。签名机制赋予用户极大的自主控制权,也意味着一旦签名落入他人之手,同样的权力可以被滥用。
很多安全事故告诉我们,签名本身就是一把”双刃剑”:它能确保安全,也可能因为用户粗心而打开资产的大门。从比特币的UTXO签名到以太坊的Permit授权,再到未来账户抽象的代码注入,每一步创新都在拓展签名的应用边界。
如果用户没有意识到”签名即权力”的含义,那么再先进的技术也可能被社工攻击所击破。反之,只要我们养成良好的习惯——不盲目签名、看懂再签名、管理已授权限——就能最大程度地享受签名机制带来的便利,而将风险降至最低。
希望本篇深入探讨能够帮助技术向的区块链爱好者和开发者更加全面地理解数字签名在加密货币中的作用与隐患,能够在签名的时候认真思考一下在签署什么内容,在追求去中心化自由的同时也守护好自己的数字资产安全。