Dev.to WebDev 🛠 Dev 👁 0 📖 2 min read

What an AI-generated PNG actually carries — and what a screenshot of it doesn't

I generated one image with OpenAI's image model and then took it apart. The point wasn't the picture — it was to see what "proof this is AI" looks like inside a real file, and how fast it disappears. The origin

I generated one image with OpenAI's image model and then took it apart. The point wasn't the picture — it was to see what "proof this is AI" looks like inside a real file, and how fast it disappears.

The original file

The PNG came out at 1536×1024. Besides the usual IHDR/IDAT/IEND chunks it had one extra: a caBX chunk of about 21 KB. That's a C2PA manifest — Content Credentials — stored in a JUMBF box.

Reading it with the official Python binding:

import c2pa
with c2pa.Reader("sample.png") as r:
    print(r.json())

The interesting parts:

  • Signer: OpenAI OpCo, LLC
  • Generator: OpenAI Media Service API
  • Digital source type on the creating action: http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia

That last field is the one that actually answers "was this made by generative AI?". The word trained matters: algorithmicMedia without it means procedural computer graphics, not a model.

"Invalid" doesn't mean tampered

The overall validation_state came back Invalid. My first instinct was "the signature is broken". It isn't. The per-check results tell a different story:

  • claimSignature.validated — pass
  • assertion.dataHash.match — pass (pixels unchanged since signing)
  • timeStamp.validated — pass
  • signingCredential.untrusted — fail
  • signingCredential.invalid — fail ("certificate missing required EKU")

So the content and the claim are intact; what fails is whether the signer's certificate is on the C2PA trust list and carries the extended key usage the spec now requires. If you build anything on top of C2PA, report those two questions separately — "changed after signing?" and "trusted signer?" — or you'll tell users a genuine file was tampered with.

Then I re-saved it as JPEG

One conversion with a stock image tool (sips on macOS) and the manifest was gone. strings on the JPEG found zero c2pa references. Same thing happens with a screenshot, and with most social and chat uploads, which re-encode everything.

That's the uncomfortable part: Content Credentials prove origin when present, but their absence proves nothing. Most AI images you'll actually be asked about — in a group chat, a dating app, a refund dispute — have already lost them.

What that means for checking images

The order that held up for me:

  1. Read the file first. If signed credentials say generative AI, you're done — that's stronger than any classifier.
  2. Check metadata (IPTC source type, software tags). Useful, but editable by anyone.
  3. Only then use a pattern model, and treat its output as a probability, not a verdict.

I ended up building this order into a small browser-based checker, Image or AI, mostly because every detector I tried skipped straight to step 3 and never said what its answer was based on. Credentials and metadata are read client-side with @contentauth/c2pa-web (WebAssembly), so the image doesn't leave the device for those steps.

If you work with provenance data, the thing I'd most like other tools to copy is simple: show which evidence a verdict came from.

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.