DEV Community

Francisco López
Francisco López

Posted on

Your Phone Already Has the Hardware to Prove a Photo Is Real. Nothing Uses It.

Your Phone Already Has the Hardware to Prove a Photo Is Real. Nothing Uses It.

#opensource #mobile #security #reactnative

The Problem Is Already Here

In 2025 Adobe's Content Authenticity Initiative reported that 97% of organizations have encountered AI-generated content being used against them. Deepfakes, synthetic product photos, fabricated evidence.

Meanwhile every phone in your pocket has a tamper-resistant cryptographic chip sitting idle. Secure Enclave on iOS. StrongBox or TEE on Android. Hardware designed to sign things in a way that can't be extracted or faked.

Nobody is connecting these two facts.

C2PA: The Standard Nobody Talks About

C2PA is an open standard from Adobe, Microsoft, Intel and others. It works like HTTPS but for media files. A cryptographic manifest gets embedded directly into the JPEG containing:

  • What device captured it
  • When and where
  • Every edit made after capture
  • A signature that breaks if a single pixel changes

Leica, Sony and Nikon already ship C2PA in some cameras. But on mobile, where 90%+ of photos are taken? Almost nothing.

Enter attestation-photo-mobile

I built attestation-photo-mobile to close that gap.

It's a React Native package. You bring your own camera lib, take a photo, and pass the path. The package does the rest: hashes the image, signs it with hardware-backed keys, and embeds a full C2PA manifest before the file ever touches disk.

How It Works

The architecture has three layers:

  1. Native layer (Swift/Kotlin): Handles hardware keystore access. Provisions an ECDSA P-256 key inside Secure Enclave or StrongBox. This key never leaves the hardware.
  2. Rust layer (c2pa-rs): Builds the JUMBF manifest, computes the asset hash, constructs the C2PA claim. I tried doing this in pure JS first. Don't.
  3. React Native bridge: Exposes a single signPhoto(path) function and a useAttestedCapture hook that handles key provisioning, location prefetch, and error wrapping.

Usage

import { useAttestedCapture, saveToGallery } from '@rolobits/attestation-photo-mobile';

function CaptureScreen() {
  const { signPhoto, isReady } = useAttestedCapture({
    includeLocation: true,
    appName: "My App",
    nonce: "server-challenge-token",
  });

  const onCapture = async (photoPath) => {
    // Sign and embed C2PA manifest
    const signed = await signPhoto(photoPath);

    // signed.trustLevel -> "secure_enclave" | "strongbox" | "tee"
    // signed.embeddedManifest -> true
    // signed.signature -> SHA-256 hex of original asset

    await saveToGallery({ filePath: signed.path });
  };
}
Enter fullscreen mode Exit fullscreen mode

The output JPEG can be verified with any C2PA tool. Upload it to verify.contentauthenticity.org or run:

cargo install c2patool
c2patool verify output.jpg
Enter fullscreen mode Exit fullscreen mode

What Gets Blocked

The SDK runs device integrity checks before signing. Jailbroken or rooted devices get E_COMPROMISED_DEVICE. No Secure Enclave or StrongBox? E_NO_TRUSTED_HARDWARE. You can control this with requireTrustedHardware: true|false.

Where This Actually Matters

This isn't a solution looking for a problem. These are scenarios where someone has a financial incentive to submit fake photos:

  • Insurance claims: Snap damage photos in-app. Each one is hardware-signed with device, location, timestamp. The adjuster's backend verifies the manifest automatically.
  • Marketplace listings: Verified photos for cars, real estate, rentals. Buyers know the images aren't AI-generated or recycled from 2019.
  • Field inspections: Construction sites, equipment audits. Timestamped proof of conditions for compliance.
  • KYC: Selfie-based identity verification where the photo is provably from a real device, not a generated face fed through a virtual camera.

This is a v1. Here's what's missing:

  • Self-signed certificates. The signing key has no CA chain. Verifiers will show a valid signature but "unknown signer." This means tamper detection works today but attribution doesn't. CA integration is the next priority.

👉 GitHub: RoloBits/attestation-photo-mobile

Top comments (0)