乐于分享
好东西不私藏

你怎么知道刚下载的App没有被植入病毒?那个"验证中…"进度条,和一个生日悖论

你怎么知道刚下载的App没有被植入病毒?那个"验证中…"进度条,和一个生日悖论

昨天我更新微信,App Store弹出”正在验证…”,转了两秒。我盯着那三个字看了一会儿。我的手机正在做一件事:确认这个安装包是真正的微信,而不是黑客篡改过的”假微信”。

不是靠公司信誉。不是靠”它是从App Store下的”。是靠在安装包上运行一个叫SHA-256的数学函数,它生成一个独一无二的”数字指纹”。如果指纹和微信官方发布的指纹不一样,哪怕只差一个数,系统会判定”文件被篡改过”,拒绝安装。

这个”指纹”背后的数学,是一个你在中学就学过的概率现象,生日悖论。而2017年,Google花了6500年CPU时间,就是为了证明:旧版本的”指纹”已经不够安全了,全世界必须立刻升级。


先搞清楚一件事:

哈希函数不是你存的”密码”。它是一个数学函数,输入任何长度的数据,输出固定长度的”指纹”。最重要的安全属性是碰撞抗性:你不可能找到两个不同的输入,产生完全相同的”指纹”。

2017年2月23日,Google安全团队宣布:我们找到了。 两个完全不同的PDF文件,经过旧版SHA-1哈希后,产生了完全相同的指纹。这意味着一个攻击者可以创建一份”合法合同”,拿到你的数字签名后,再换成”欺诈合同”,而签名验证会通过,因为指纹一模一样。SHA-1死了。全世界浏览器在几天内停止信任它。

而Google做到这件事的方法,不是穷举了整个搜索空间,是用了一个概率课上的技巧。生日悖论。



生日悖论,为什么23个人就够了

一个房间里多少人,至少两人生日相同的概率超过50%?

直觉会说”365天,至少需要183个人吧?” 数学说:23个人就够了。

不是比”有人生日和你相同”,是比”任意两个人有相同生日”。23个人中,可能的”两人配对”数是 C(23,2) = 253对。每一对有1/365概率匹配。253对交叉比较,概率远超高直觉估计。实际计算:超过50%。

现在把这个逻辑用在哈希攻击上。 攻击一个哈希函数不需要穷举所有可能,只需要穷举平方根个。生日悖论说:在一个N个可能输出的空间里,你试约√N次就能找到一次碰撞。

哈希算法 输出位数 暴力破解 生日攻击(√N)
SHA-1 160位 2^160 2^80(Google做成了)
SHA-256 256位 2^256 2^128(宇宙年龄级)

SHA-1之所以死,是因为2^80已经落入”人类+GPU集群”的能力范围,Google用了110个GPU跑了一年多。而SHA-256还安全,因为2^128仍然大得即使全世界的GPU都来跑,也跑不到宇宙寿命的零头。



SHA-1之死,不是你该担心的,但你应该知道发生了什么

Google花了约6500年CPU时间的等效计算量(大规模并行GPU集群跑了一年多),找到了两个PDF,它们的SHA-1指纹完全碰撞。

这不是”军队”攻击”密码学家”。是“密码学家”在保护全世界,他们花巨大精力撞塌一个系统,只为向全世界证明:这把锁已经锈透了,必须立刻换。几天之内,Chrome、Firefox、Safari陆续停止信任SHA-1证书。全世界所有网站,从你现在看的这个页面,到你的银行,必须使用SHA-256或更强的哈希算法。

你现在下载App时,后台在跑的就是SHA-256。那个小小的”验证中……”进度条,是一次2^128级别的数学担保。


不止是下载App,指纹在保护你的每一次信任

Git提交记录:你用Git管理代码时,每一次提交都以SHA-1哈希命名(Git也在逐步迁移到SHA-256)。如果两份不同的代码产生了相同的哈希,就意味着”同一个签名可以代表两份不同的代码”。

文件去重:你手机清理空间时,系统怎么知道两个文件是”同一个”?不是比较文件名,是比较哈希指纹。相同哈希=相同文件。

区块链:比特币每一个区块都包含前一个区块的哈希,任何人篡改一个历史区块,所有后续区块的哈希全部失效。这就是”链”的来源,每一个环节的指纹被锁在下一个环节里。


想亲手验证?

  1. 最简单:打开微信 → 我 → 设置 → 关于微信 → 你正在用的是一个被SHA-256保护着的App。上亿行代码,数学保证它没有被篡改过。

  2. 进阶(电脑端):在电脑上找个文件,运行 certutil -hashfile 文件名.txt SHA256(Windows)或 shasum -a 256 文件名.txt(Mac/Linux)。你会得到一个64位的十六进制指纹。修改文件里一个字,重新运行,指纹全变了。这就是”雪崩效应”,改动1%的输入,输出变化超过50%的比特位。

  3. 终极:约23个朋友,拉个群统计生日。验证一下,任意两人生日相同的概率,是不是真的超过50%。这是本文所有数学的起点,一个挑战了你直觉的概率事实。


你下载App时那个”验证中……”的进度条,背后是一道看似简单的数学问题:有没有两个不同的文件,产生完全相同的指纹?SHA-1,从1995年到2017年,人类说”没有”。直到Google花了6500年CPU时间,找了两年,宣布:有。全世界在几天内完成了升级。

你现在用的SHA-256,还安全,因为2^128太大。大到所有GPU联合起来也需要宇宙年龄级别的计算时间。下次App更新时看那个”验证中……”一秒。那一秒里,你的手机在确认:这个安装包的SHA-256指纹,和开发者发布的指纹,是同一个。而如果有人想骗过它,他需要先解决一个比宇宙还大的数学题。


如果这篇让你多看了一眼那个”验证中…”,点右下角「推荐」,让更多人知道App更新的那一秒在干什么。