一行代码缺失,千万美元蒸发: SecondFi 钱包 Ed25519 签名漏洞全解密
SecondFi 钱包事件一份面向开发者的加密学事后剖析背景2026 年 6 月 21 日至 23 日SecondFi原 YoroiCardano 钱包中的一个致命漏洞导致约 1610 万 ADA当时价值约 240 万美元从 374 个用户钱包中被盗。根源仅仅是在 Ed25519 签名实现中少写了一行代码。作为开发者我们常常把加密库当作黑盒来用。这次事件残酷地提醒我们如何使用加密原语和原语本身同样重要。让我们一步步拆解到底出了什么问题、为什么会发生以及如何避免重蹈覆辙。技术拆解Ed25519 签名本该怎么做Ed25519 是 RFC 8032 定义的一种确定性签名方案。与 ECDSA其随机数重用已是众所周知的灾难不同Ed25519 的设计初衷就是彻底消除随机数失败的风险, 它从私钥材料和消息中确定性地派生出临时随机数nonce。对于 Cardano 的扩展 Ed25519 变体钱包存储一个 64 字节的扩展私钥分为两部分kL第 0–31 字节签名标量kR第 32–63 字节秘密随机数后缀每个钱包独有永不公开正确的签名流程如下r SHA-512(kR || M) mod L # 随机数由秘密 消息派生 R r * B # R 是公开的 k SHA-512(R || A || M) mod L # 挑战标量 S (r k * kL) mod L # 签名分量最终签名是(R, S)对。这个设计安全的原因确定性同一消息 同一密钥 同一签名无需依赖 RNG秘密参与随机数r依赖kR而kR永远不会离开设备可验证任何人都可通过[S]B R [k]A验证无需知道私钥SecondFi 实际做了什么SecondFi Android 10.0.3 版本在从 BIP32-Ed25519 派生层向签名适配器层传递数据时遗漏了关键的kR秘密前缀。只有签名标量被传给了底层签名器。有缺陷的实现计算随机数的方式是r SHA-512(M) mod L仅此而已。没有任何秘密成分只有交易体哈希, 而这是链上公开可见的。为什么这是灾难性的当随机数可以公开计算时攻击者只需一条链上签名就能恢复私钥。给定任何交易中的公开值M被签名的消息交易体R公开随机数点A公钥S签名分量攻击者计算r SHA-512(M) mod L # 和漏洞签名器一样 k SHA-512(R || A || M) mod L # 和验证器一样 s (S - r) * inverse(k) mod L # 恢复私钥一条签名一笔交易你的私钥就归别人了。安全研究员 Charles Guillemet 现场演示了这一点他从主网上拉取签名仅凭链上信息就重建了私钥。时间线日期事件6 月 8 日SecondFi Android 10.0.3 发布包含有缺陷的签名器6 月 12 日早期用户交易已经开始泄露密钥6 月 21–23 日两个独立攻击者团伙系统性清空 374 个钱包6 月 22–23 日SecondFi 承认问题进入维护模式6 月 22 日SecondFi 紧急将约 1.29 亿 ADA 转移至第三方托管机构6 月 24 日补丁发布7 月 22 日SecondFi 宣布永久关闭根本原因未经审计的 SDK漏洞是在 6 月 8 日引入的当时一个名为trantor的未经审计的第三方实验性 SDK由一名独立开发者发布在 npm 上替换了 EMURGO 此前审计过的签名模块。这是一个关键的教训绝不能在生产环境中用未经审计的代码替换经过审计的加密代码, 尤其不能跳过完整的安全审查。Tibane Labs 的取证报告证实有漏洞的签名器正是trantorSDK它替换了经过验证的 EMURGO 构建版本。问题不在于 SDK 本身的意图而在于它如何与 Cardano 扩展 Ed25519 签名流程集成, 秘密前缀根本没有通过适配器层传递。代码级分析有漏洞的实现简化版importhashlib# 漏洞完全省略了秘密前缀 kRdefflawed_sign(private_key_scalar,message):# 缺失kR秘密随机数前缀# 本应是r SHA512(kR || message) mod L# 有漏洞随机数只由消息派生rSHA512(message)%L# 可公开计算Rr*B kSHA512(R||public_key||message)%L S(rk*private_key_scalar)%Lreturn(R,S)正确的实现RFC 8032importhashlibdefcorrect_sign(extended_secret_key,message):# extended_secret_key kL (32 字节) kR (32 字节)kLextended_secret_key[0:32]kRextended_secret_key[32:64]# 正确随机数由秘密前缀 消息派生rSHA512(kR||message)%L# 秘密且不可预测Rr*B kSHA512(R||public_key||message)%L S(rk*kL)%Lreturn(R,S)概念验证玩具示例下面这个简化的 PoC 展示了漏洞原理importhashlib L2**127-1# 不是真正的 Ed25519 阶仅为演示defH(*parts):hhashlib.sha512()forpinparts:h.update(pifisinstance(p,bytes)elsestr(p).encode())returnint.from_bytes(h.digest(),little)%Ldefinv(x):returnpow(x,-1,L)# 受害者的私钥玩具示例secret_s98765432123456789public_Asecret_s# 真实 Ed25519 中 A s * BMbcardano tx body hash, toy example# 漏洞签名器前缀被丢弃随机数仅由消息决定rH(M)Rr# 真实 Ed25519 中 R r * BkH(R,public_A,M)S(rk*secret_s)%Lprint([受害者签名])print(A ,public_A)print(R ,R)print(S ,S)# 攻击者从公开数据恢复私钥r_publicH(M)recovered_s((S-r_public)*inv(k))%Lprint(\n[攻击者])print(恢复出的私钥:,recovered_s)print(匹配:,recovered_ssecret_s)修复方案应该怎么做1. 使用经过审计的库永远不要自己造加密轮子。使用成熟、审计过的库Rusted25519-dalek标准且经过审计的实现JavaScript/TypeScriptnoble/ed25519或tweetnaclPythonpynacllibsodium 绑定对于 Cardano请使用Cardano Serialization Libraryemurgo/cardano-serialization-lib它经过审计并遵循正确的扩展 Ed25519 规范。2. 在所有层级保留秘密前缀在通过适配器层传递密钥时确保完整的扩展私钥kL和kR两者都保留// 正确传递完整的 64 字节扩展私钥fnsign_transaction(extended_secret:[u8;64],message:[u8])-Signature{letkLextended_secret[0..32];letkRextended_secret[32..64];// kR 必须用于随机数派生letrsha512(kR,message);// ...}3. 绝不用未经审计的代码替换已审计代码trantorSDK 在 6 月 8 日替换了 EMURGO 的审计实现。这种变更本应触发完整的安全审查加密正确性验证测试分阶段发布并伴随监控4. 实施加密正确性的回归测试测试随机数派生是否正确#[test]fntest_nonce_derivation_includes_secret_prefix(){letsecretgenerate_test_secret();letmessagebtest message;letsig1sign(secret,message);letsig2sign(secret,message);// 确定性同一密钥 同一消息 同一签名assert_eq!(sig1,sig2);// 不同消息应产生不同随机数letsig3sign(secret,bdifferent message);assert_ne!(sig1,sig3);// 关键验证随机数不是简单的 SHA512(message)// 这需要访问内部状态或已知答案测试}5. 审计所有第三方依赖trantorSDK 由一名独立开发者发布从未被审计。在集成任何加密依赖之前审查源代码检查已知漏洞验证维护者的信誉考虑进行全面安全审计开发者的核心要点Ed25519 设计上是确定性的——随机数由SHA-512(secret_prefix || message)派生。如果省略秘密前缀随机数就变成了公开可计算的。当随机数可预测时一条签名就足以恢复你的私钥。这比 ECDSA 随机数重用更糟糕, 后者通常需要两条签名。漏洞是通过用未经审计的代码替换已审计代码引入的。加密代码不是“即插即用”的, 集成方式至关重要。一旦密钥在链上被泄露它就永远泄露了。区块链交易是不可逆的。EMURGO 警告用户将受影响的助记词导入其他钱包并不能降低风险, 被泄露的地址必须彻底放弃。攻击窗口只有短短两周6 月 8 日至 6 月 21 日但已有 374 个钱包被清空。当漏洞如此容易利用时攻击者可以行动得极快。最后的思考这不是一次复杂的攻击。没有零日漏洞没有钓鱼活动没有智能合约漏洞也没有助记词被偷。攻击者只是读取了区块链然后做了一些算术。正如 MyCrypto 创始人 Taylor Monahan 所指出的这比 2011 年早期的比特币钱包漏洞还要严重。这是一次流程上的失败, 在未审查的情况下替换审计过的加密代码未能测试集成然后将其推送给数百万用户。SecondFi 将永久关闭。374 名用户失去了他们的资金。一位支持 Cardano 九年的用户损失了为退休而积攒的 998,000 ADA。所有这一切只是因为少写了一行代码。

相关新闻

Windows 11与VSCode终端美化全攻略:从字体配色到Oh My Posh实战

Windows 11与VSCode终端美化全攻略:从字体配色到Oh My Posh实战

1. 从“黑框框”到高效工作台:为什么我们需要美化终端? 每次打开Windows 11那个经典的黑色命令提示符(CMD)或者PowerShell窗口,你是不是也感觉有点“复古”?一个简单的白字黑底界面,字体可能还…

2026/10/27 17:04:53 阅读更多 →
Python图像边缘检测实战:从Sobel到Canny算法原理与调优指南

Python图像边缘检测实战:从Sobel到Canny算法原理与调优指南

1. 项目概述:从“看见”到“看清”边缘在计算机视觉的世界里,让机器“看见”只是第一步,让它“看清”物体的轮廓和结构,才是理解图像内容的关键。图像边缘检测,就是实现这一目标的基础技术。简单来说,它就像…

2026/10/25 11:34:53 阅读更多 →
滑翔伞机翼(Wingsuit

滑翔伞机翼(Wingsuit

为你带来具有高度物理拟真性、空气流体力学模拟、动态风阻判定以及实时物理形变的殿堂级单键高燃街机游戏——「赛博原力:滑翔伞机翼(Wingsuit / 重力势能滑翔、上升热气流与极限低空擦墙)」。前面我们写过了太空漂移、刚体连缀、…

2026/10/22 19:36:05 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/27 17:33:32 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/28 7:28:00 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/28 9:02:11 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/27 18:20:50 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/28 9:00:54 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/28 7:29:02 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 13:55:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 9:01:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 19:19:37 阅读更多 →