Git要换SHA-256了,代价谁算过

Git SHA-256 migration

前两天刷到 GitButler 的一篇长文,标题直接开炮:Git 3.0 把默认哈希算法从 SHA-1 换成 SHA-256,将是一个代价高昂的错误。

这篇文章的语气很冲,但论点扎实。我看完之后,第一反应不是"密码学该不该升级",而是一个更熟悉的问题:一个影响面极广的基础设施变更,决策权到底在谁手里?

升级的账本

先说结论。SHA-1 在密码学意义上确实"半破了"——2017 年 Google 的 SHAttered 攻击证明了碰撞可以被制造,2020 年的 SHA-mbles 进一步降低了成本。但这里的"破"是密码学家的标准,不是工程实践的标准。

碰撞攻击的前提是攻击者从一开始就预埋了恶意内容,需要同时准备"良性"和"恶意"两个版本。而更难防御的第二原像攻击——看到一个已有文件,伪造另一个内容不同但哈希相同的文件——即使 SHA-1 也几乎免疫。就算换成被公认为彻底废掉的 MD5,用全球所有 GPU 暴力破解一个特定文件的原像,也需要大约 160 亿年。

所以 GitButler 的核心论点不是"SHA-1 够安全",而是:SHA-256 要解决的那个问题,在实践中并没有看起来那么紧迫。而升级带来的生态碎片化,却是实打实的成本。

生态碎片化才是真正的账单

Git 之所以好用,不是因为它的哈希算法有多先进,而是因为它是通用的——所有工具、平台、CI 系统都默认说同一种语言。一旦默认算法切换,新旧仓库之间就出现了裂缝。

这不是 Git 独有的问题。Python 2 到 Python 3 的迁移,语法变化本身不大,但生态兼容让整个行业折腾了好几年。我们团队之前从 Webpack 切到 Vite,构建脚本改动本身不难,难的是生态兼容——一个内部插件不兼容,CI 配置要重写,自定义 loader 要迁移。升级方案里不会写这些,但它们才是真正吃掉时间的东西。过渡期三个月,比预估多了一倍。

Git 的 SHA-256 迁移也会走同一条路。你的依赖库还没迁移,你的 CI 平台只支持了一半,你的 code review 工具在混合哈希环境下行为不一致——这些都是升级方案里不会写、但一定会遇到的问题。

真正昂贵的不是迁移本身,而是迁移过程中新旧共存的过渡期。团队需要同时处理两种环境,每一种兼容问题都需要排查和解决。这个过程没有统一时间表,取决于生态中最慢的那个环节。

信任不在算法里

再说一个更反直觉的角度。代码供应链的真正威胁,从来不在加密算法上。

GitButler 举了个很实在的例子:npm 供应链投毒。攻击者不需要花几十万美元制造 SHA-1 碰撞,只需要拿下某个被广泛依赖的包的维护者权限,注入恶意代码。下游项目自动拉取,根本不会去校验哈希值。

我之前带团队做依赖安全审计时发现一个挺尴尬的事实:我们十几个项目的 package.json 里,没有一个团队会逐条校验依赖包的 SHA 校验和。大家信任一个包的依据是名字、版本号和维护者的声誉——跟哈希算法是 SHA-1 还是 SHA-256 没有半毛钱关系。

从管理视角看,代码供应链的信任基础不是加密算法,而是权限管理、维护者审核、依赖审计这些"不性感但有用"的脏活。换一个哈希函数不会让这些问题消失。安全投入应该跟着威胁模型走,而不是跟着密码学论文走。

升还是不升

如果有人问我"我们团队要不要第一时间升 Git 3.0",我目前的判断是:先不动,但保持关注。

原因不是 SHA-256 不好,而是投入产出比不对。它要防范的威胁对我们这个量级的团队来说理论上存在但实践中概率极低,而升级的代价——生态兼容性测试、工具链更新、团队学习曲线——是当下就要支付的。最怕的是升到一半卡住,工具支持不完整,团队不得不同时维护两种哈希格式,那种状态最容易出错。

不过我承认,写到这里我也在想:是不是每次基础设施升级我都是这个反应?"先不动,保持关注"——这到底是理性判断,还是惯性思维在作怪?

Git 核心团队做了技术准备,但生态的就绪程度才是决定迁移时机的关键。这个判断放在别的场景也成立——技术本身是对的,但生态节奏不对,推进就是会碰壁。

我们团队之前从 Node.js 14 升到 18 也有类似经历。升级文档说得很轻松,但实际操作时发现一个内部监控 SDK 在新版 Node 上行为不一致,查了两周才定位到底层 HTTP 代理库的连接池策略变了。这类"没人提到的兼容问题"才是升级的真实成本。每次都是。

Total votes: 1

添加新评论