2021年8月,苹果宣布将在每张照片上传到iCloud之前扫描你的iPhone照片。同年9月,在两周的争议后撤回了提案。2022年12月,官方宣告计划终止。与此同时,2022年,欧盟委员会提出了一项规定,要求WhatsApp、Signal和Telegram执行与苹果撤销的提案完全相同的操作。这项法规,即Chat Control,目前仍在欧洲理事会中推进讨论。

这两项尝试都依赖同一个算法:一个实现于40行Python代码的64位感知哈希算法。这不是夸张,甚至不是比喻。确实只有40行,在阅读完这篇文章后,您可以在自己的机器上运行它的实现版本。

大量的公众讨论——无论是在西班牙还是其他地方——都发生在参与者对该机制的工作原理不了解的情况下。法规的讨论充满了政治色彩(“隐私与儿童安全”对立),而技术核心却如同黑箱。本篇文章将扮演该黑箱的解药。如果读完后您想要发表观点,您可以基于技术事实。如果不想,那至少您已经了解他们让您接受的是什么。

问题:SHA-256无法识别两张图片是同一张

任何开发者第一个冲动的解决方案可能是用SHA-256。如果两张图片生成了相同的哈希值,那么它们就是同一张图片。简单、快速、加密安全。

但这不起作用。

import hashlib

def sha256(path):
    with open(path, "rb") as f:
        return hashlib.sha256(f.read()).hexdigest()

# 同一张图片,不同压缩
sha256("foto.jpg")           # "a7f3..."
sha256("foto_reencoded.jpg") # "9c2e..."  (完全不同)

只改变一个比特——例如JPEG压缩质量从95降低到90,或者从WebP格式转换为JPEG,甚至亮度的微小调整——SHA-256生成的哈希值都会完全不同。数据清晰地证明:加密相似性设计为完全不容忍差异,这是一种特性,而非漏洞。

为了检测“相同的图片即使压缩不同”,需要一个容忍度更高的算法。这意味着需要一个感知哈希:一个能在图片内容不变而细微改变的情况下仍然保持一致的64位签名。

aHash:亮度平均值

最早有用的方案被称为平均哈希(Average Hash)或aHash。其理念非常简单:

import numpy as np
from PIL import Image

def average_hash(path, size=8):
    img = Image.open(path).convert("L").resize((size, size))
    arr = np.asarray(img, dtype=np.float32)
    mean = arr.mean()
    bits = (arr.flatten() > mean).astype(int)
    return "".join(str(b) for b in bits)

def hamming(a, b):
    return sum(x != y for x, y in zip(a, b))

图像被缩小为8×8像素的灰度图,计算亮度平均值,每个像素亮度大于平均值时为1,否则为0。结果是64位,代表全局亮度分布。

两张“相同”的图片会生成汉明距离很小的哈希值(≤ 5 位不同)。两张不同的图片则会有大的汉明距离(40+ 位)。这种方法能在图片被缩放、稍微裁剪或者重新编码时起作用。但如果有人调整了对比度或全局亮度,aHash就会失效。这是第一步。

dHash:相对梯度

下一步是2011年由Neal Krawetz提出的差异哈希(Difference Hash),简称dHash:

def difference_hash(path, size=8):
    img = Image.open(path).convert("L").resize((size + 1, size))
    arr = np.asarray(img, dtype=np.float32)
    diff = arr[:, 1:] > arr[:, :-1]
    return "".join("1" if v else "0" for v in diff.flatten())

与其测量绝对亮度,它测量水平相对梯度:如果某个像素比右边的像素更亮,则为1。如果整个图片亮度暗了30%,相对梯度仍然保持一致。dHash能够应对对比度、伽马值、色彩调节的变动——这些情形下aHash会失效。

40行Python代码,加上依赖库里的PIL,短短两周研发出了引导当年欧盟最具争议法规的主要工具。

从40行代码到全球基础设施

你用average_hash和difference_hash完成的操作实际上是许多线上图片处理平台所依赖技术的基础。

Microsoft PhotoDNA(2009年)。由Dartmouth的Hany Farid与微软研究院共同开发,用于检测儿童性虐待材料(CSAM)。这是一种与上述类似的进阶版本:将图片简化为短哈希值,具有耐压缩性,可以通过距离进行比对。具体实现是专有的,但理念与上述算法一致。微软宣称PhotoDNA每月为主要平台处理数十亿张图片。

Meta PDQ(2019年)。Meta(前Facebook)内部开发并作为ThreatExchange的一部分开源发布的变种版本。与PhotoDNA不同,这种工具的代码是公开的,可以阅读、运行、理解。Meta的立场是,安全性不应该依赖于算法的秘密,而是系统整体的难以攻破性。

YouTube Content ID(2007年)。使用适应于视频的感知哈希:将每次上传的视频分片为帧上的指纹,与版权库中的内容对比。即使重新编码、裁剪随机标志、小幅旋转,它也能检测到重复上传。

Google Photos、Apple Photos 和 Amazon Photos。当你的手机告诉你“这张照片已经从iPad上传到了iCloud”时,它并不是比较图片的字节,而是使用感知哈希变体来识别图片内容,即使压缩、格式或轻微裁剪不同。

Apple NeuralHash(2021年)。苹果撤回的提案。NeuralHash并非传统pHash,而是一种卷积神经网络,通过训练实现对变换(旋转、裁剪、压缩)的不变性,并输出96位局部敏感哈希(Locality-Sensitive Hashing)。尽管在技术上比PhotoDNA更复杂,但其核心理念相同:一个短、健壮、可比较的指纹。

从PhotoDNA到NeuralHash,模式是一致的:同一个算法在不同的技术名称和优化版本下,已成为网络中的无声基础设施。大多数用户并不知道它的存在;大多数开发者只听说过,但从未实现过它。而现在,欧洲议会正准备通过法规使其成为加密通信标准的一部分。

瓶颈

如果算法是完美的,争议将很简单。但它并非如此。存在四个结构性问题,了解这些问题是形成看法的前提。

错误正报

两张完全不同的图片可能生成相同的哈希值。对于64位哈希,总共有2^64 = 18万亿可能值,而合理图片(非随机噪声)数量远少于此,且存在统计规律。尽管发生的概率很低,但仍然可能存在。

2021年苹果风波期间,有用户记录了NeuralHash误报的例子:一只狗和一件抽象雕塑拥有相同的哈希值。虽然真实误报率较低,但仍存在。苹果宣称“一年每万亿账户一个误报”,但研究者质疑此数据,且展示出通过微小改动,误报率可以增加几个数量级。

错误否认

将图片旋转10度,裁剪20%的右边框,或者水平翻转,大多数感知哈希算法都会失效。更先进的算法(比如带离散余弦变换的pHash,或者训练有不变性的NeuralHash)能承受更多变化,但它们都有一个临界点。

这意味着动机明确的用户可以通过任何手机预装工具绕过系统:旋转图片、低质量压缩、添加10像素边框。哈希数据库将无法识别修改后的图片,非法内容可以轻松逃脱检测。

对抗性冲突

这是最严重但媒体讨论最少的问题。2021年8月18日,苹果宣布计划不到两周后,一名叫Asuhariet Ygvar的研究者就在GitHub上发布了NeuralHash的逆向工程,以及可生成冲突图像的工具。

数天后发布的工具可以制造伪造冲突:两张完全不同的图片生成相同的哈希值,甚至根据目标图片生成带有相同哈希值的全新图片。

2021年,由Johns Hopkins大学的Jonathan Prokos团队以及Matthew Green等研究者发表的论文_《“眯起眼就够了”:通过对抗性机器学习攻击感知哈希》_(USENIX Security)正式定义了这一攻击形式。他们证明了,对任何已知的感知哈希算法,可以生成:

  • 任意冲突:任意两张图片生成相同哈希值。
  • 目标预测:针对目标图片,生成在视觉上完全不同却有相同哈希值的图片。

这一特性使动机明确的攻击者能够轻松引发混乱。例如,攻击者可以向目标用户发送哈希值匹配CSAM已知数据库的合法图片,从而触发错误警报。虽然系统最终可能会人工审查并恢复正常,但由此引发的大规模攻击可能导致系统崩溃或误用。

哈希数据库的控制权

最后是一个政治问题。与之对比的哈希数据库由NCMEC(美国国家失踪与被剥削儿童中心)控制,这是一家私营机构。尽管这些哈希会与欧洲和其他国家的供应商共享,但决定哈希加入或移除的权力仍在美国。

这形成了一个全球唯一的真相控制点,其后果却很少被讨论。假如NCMEC决定添加不完全属于CSAM的哈希,或者一个政府施压——无论是美国还是其他要求使用该数据库的国家——要求加入与政治异议、LGBTQ内容或新闻泄密相关的哈希?算法无法分辨,只会检测你告诉它检测的内容。

争议:苹果2021年与欧盟2026年

这正是技术争议背后的政治动因。

  • 2021年8月5日。 苹果宣布了三项“儿童保护”功能,其中之一是在上传到iCloud之前,在设备端扫描每张照片,使用NeuralHash与NCMEC数据库对比。30次匹配触发警报,人工审查后报告给相关机构。

  • 在接下来的两周,反应激烈。Matthew Green(Johns Hopkins)和Ross Anderson(剑桥大学)联名撰写了批评论文《我们的口袋里的漏洞:客户端扫描的风险》(2021年,由14位密码学与安全研究专家联合签署),指出设备端扫描基础设施本身就是问题所在。一旦构建,政府可以要求用于其他目的,苹果可能难以拒绝。

  • 在NeuralHash技术的漏洞被日渐揭露后,2021年9月3日,苹果宣布推迟这一功能。2022年12月,苹果正式终止了该功能,转而推出可选的“高级数据保护”(为iCloud提供端到端加密)。

  • 2022年5月11日。 欧盟委员会提出了《防止和打击儿童性虐待法规》(CSAR)的提案,媒体称之为“Chat Control”。这一提案要求通信服务提供商(WhatsApp、Signal、Telegram、iMessage等),在司法命令下检测用户通信中的CSAM内容,包括允许使用设备端扫描技术。

欧盟的提案与苹果的提案几乎完全一致。批评者(包括当初质疑苹果提案的学者)明确指出这一点。尽管自2022年以来,经过了欧洲议会与欧洲理事会的会议审议,部分极端条款得以缓和,但技术方向未有实质改变:欧盟希望让设备端扫描成为标准工具。

2026年,Chat Control仍在推进。尽管投票被推迟,未来几年的监管方向已逐渐明朗,即努力在4.5亿欧洲人中建立技术义务的标准。

你能做些什么

事实很明确:理解算法工作原理是参与这场争论的必要前提。这不是意见而是分析。

以下是具体行动,按成本升高排序:

  1. 运行本文中的代码。 复制average_hash和difference_hash,将其应用于你的快根.argv.mkdir abs code photos,测量距离。观察亮度如何破坏aHash,且dHash如何耐受。40行代码,30分钟搞定。

  2. 阅读PDQ白皮书。 在GitHub上(facebook/ThreatExchange)找到文档,这是一套真实生产环境中的代码。理解从pHash到PDQ的演化,只需几个小时。

  3. 阅读学术论文《我们口袋里的漏洞》。 (Anderson et al., 2021, arXiv:2110.07450)这是反对客户端扫描的参考文献,是密码学领域的重要论文。

  4. 追踪欧盟议会与理事会对CSA法规的投票进展。 公共工具(如Pirate党欧洲议员Patrick Breyer运营的_chatcontrol.eu_)可以跟踪法规当前的状态。

需要避免的是:在没有看到算法实际运作前发表意见。这不是技术洁癖,而是诚实。正在成为争论核心的算法,仅四十行代码,任何开发者都能理解。如果你还没读过术语实现,你对相关法规的了解至多是别人推文的回响。

问题不是欧盟是否会规范加密通信,而是我们是否会基于理性,而不是无知,参与讨论。

参考资料

  • Krawetz, Neal. 《查找图像》,HackerFactor博客,2011年。感知哈希与差异哈希的经典介绍。
  • Meta. 《PDQ——用于图像相似性的感知哈希》。GitHub: facebook/ThreatExchange,2019年。
  • Prokos, J.; Fendley, N.; Green, M.; Jois, T. M.; Cao, Y. 《“眯起眼就够了”:通过对抗性机器学习攻击感知哈希》,USENIX安全会议,2023年(arXiv:2112.09283)。
  • Abelson, H.; Anderson, R.; Bellovin, S. M.; et al. 《我们口袋里的漏洞:客户端扫描的风险》,arXiv:2110.07450,2021年。
  • Apple. 《CSAM检测技术概要》,2021年8月。已归档;不再官方发布。
  • Ygvar, A. 《AppleNeuralHash2ONNX 》,GitHub,2021年8月。逆向工程与冲突生成器。
  • 欧洲委员会. 《防止和打击儿童性虐待法规提案》,COM(2022) 209 final,2022年5月11日。
  • NCMEC. 网络报告统计,年度统计数据。

本文原文为西班牙语,借助AI翻译。