如何使用 C2PA 篡改时间
How to hack time, with C2PA

原始链接: https://www.da.vidbuchanan.co.uk/blog/hacking-time.html

David Buchanan 演示了 C2PA 的“排除项”功能如何削弱内容真实性。C2PA 通常会签署文件的哈希值,而可信时间戳则证明该哈希值在特定时间之前已经存在。如果将文件中的所有字节都排除在签名范围之外,恶意签署者就可以使这项声明仅涵盖空字符串的 SHA-256 哈希值。此后对文件进行编辑,签名和时间戳仍会保持有效。 Buchanan 的演示方法是:先拍摄一张彩票,附加真实的 C2PA 签名和可信时间戳,然后在开奖后修改彩票上的号码。元数据在密码学上仍然有效,但现有的验证工具并未明确标示这种篡改。 虽然排除整个文件很容易被发现,但范围较小的排除项也可能影响安全关键数据,而且很难自动评估。不能简单地取消所有排除项,因为 PNG 等格式在签名后发生变化时,某些字节(包括 CRC 校验和)必须随之改变。因此,Buchanan 建议为每种格式明确规定允许排除的内容,并要求验证工具拒绝任何超出规定范围的排除项。

Hacker News 最新 | 往期 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 如何利用 C2PA 篡改时间 (da.vidbuchanan.co.uk) 6 分 由 Retr0id 提交 1 小时前 | 隐藏 | 往期 | 收藏 | 1 条评论 帮助 bawolff 0 分钟前 [–] > C2PA 允许设置任意“排除项”。这些是被排除在签名计算之外的文件字节范围。 很高兴看到我们吸取了 SAML 的教训。 回复 考虑申请 YC 2027 年冬季批次! 申请截止至 11 月 2 日。 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请加入 YC | 联系我们 搜索:
相关文章

原文

By David Buchanan (aka retr0id), 2nd October 2026

The most impressive hacking stunt from cinema history comes from Kung Fury (2015), in which Hackerman hacks time itself. He uses this power to correct historic misdeeds. But what would I do with the ability to hack time? Personally I'm more afraid of the butterfly effect, so I'd just go back a few hours to tell myself the winning lottery numbers.

As it happens, that's exactly what I did, according to the cryptographically unforgeable C2PA metadata of this image:

Yes, you can tell it's photoshopped. I'm not trying to do actual lottery fraud here.

You can verify the C2PA metadata including the timestamp at https://verify.contentauthenticity.org/ (if you're reading this in the future, maybe they've introduced mitigations).

You can confirm that those are the winning lottery numbers, shown hours before the draw time, at https://www.euro-millions.com/results/28-08-2026.

A typical C2PA manifest contains two signatures. The first is the "claim" signature, and in the case of a camera app the claim might be something like "this is a captured photograph, taken at these GPS coordinates, at this time" (except expressed more formally, per the C2PA spec).

In my previous article I showed that the claim signature is approximately worthless, and we can sign whatever claims we like (at least, we can in the case of flagship C2PA implementations like the Google Pixel Camera app).

But there's usually a second signature, from a Time Stamp Authority (TSA), and this one is more interesting. We don't trust devices to tell their own time, so instead a remote server is consulted, via the RFC 3161 protocol. The server sends back a signature that asserts "yes, I saw this hash at this timestamp", and this response is embedded into the C2PA metadata. As long as we trust that the server isn't misbehaving, this proves that the data being signed existed at-or-before the specified timestamp. The TSA acts like an independent witness.

For the Pixel 10, Google decided that devices can in fact be trusted to tell their own time. I have not evaluated their "on-device trusted time-stamp" implementation yet, but I'm highly sceptical of it.

Despite this, in this article we will not be attacking the TSA: we assume it functions as advertised.

If the TSA mechanism is secure, how are we going to hack time?

We're going to use my favourite bug class: the spec footgun.

The footgun is as follows: C2PA allows for arbitrary "exclusions". These are byte ranges within the file which are excluded from signature calculations. Yup. Really. This is already known (it's literally in the spec), but for some reason nobody's done anything about it yet.

In fact, Dr. Neal Krawertz explicitly called it out in his "Big Bulleted List" of C2PA flaws published June 2025:

  • Large exclusion range. The manifest typically excludes a very large byte range from the signatures. Any excluded bytes can be altered without detection.

The only new angle here is that a malicious signer can deliberately use a large exclusion range, rather than merely doing so incidentally. We can exclude the entire file, to produce an entirely valid signature over an empty string. This allows the file to be tampered with after the fact, without invalidating the signature, and without invalidating the TSA's timestamp proof.

Time status: Hacked

So I really did take a picture of a lottery ticket, and attach a valid C2PA signature with a valid trusted timestamp. But I crafted the manifest to exclude the whole file, allowing me to photoshop it (poorly) after the numbers were announced, without invalidating any of the signatures.

Using c2patool -d to dump the manifest of my PoC file, we can see the important part:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
"c2pa.hash.data": {
  "exclusions": [
    {
      "start": 0,
      "length": 3995383
    }
  ],
  "name": "jumbf manifest",
  "alg": "sha256",
  "hash": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
  "pad": []
},

3995383 is the length of the entire file, and 47DE...uFU= is the hash of an empty string:

$ openssl sha256 -binary /dev/null | base64
47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=

The claim signature is over that hash, and the timestamp signature is over the claim signature. We're effectively signing nothing at all, but as of today all the C2PA verification tools I can find don't flag anything as unusual.

Not easily! Sure, it's trivial to detect when the entire file has been excluded and report it as invalid, but what if only a small part is excluded? How do you tell whether it's something harmless, or something that could completely change the appearance of the image if modified? (See MD5 hash collision PoCs for examples of the latter).

My first draft of this post ended here with "My recommendation is that the exclusion feature should be excluded from the C2PA spec," but it's not that simple!

The main reason exclusions exist in the first place is that certain file formats effectively require it. For example in PNG files, each chunk has a CRC32 checksum, which needs to be corrected after the signature has been embedded into the file. This would create a circular dependency, unless the CRC32 is excluded from the signature's coverage (ignoring clever mathematical tricks that could avoid invalidating the CRC).

With that in mind I think the right solution here is to carefully and explicitly specify which parts of a file are allowed to be excluded, for each supported file format, and require that verifiers enforce these constraints.

联系我们 contact @ memedata.com