c2pa_flutter 0.1.0 copy "c2pa_flutter: ^0.1.0" to clipboard
c2pa_flutter: ^0.1.0 copied to clipboard

Combined read/write C2PA Flutter plugin with manifest signing and certificate management. Uses the official c2pa-rs Rust library via FFI.

c2pa_flutter #

A Flutter plugin for reading and writing C2PA (Coalition for Content Provenance and Authenticity) manifests. Powered by the official c2pa-rs Rust library via FFI, providing full Content Credentials support for mobile apps.

pub package License: MIT

Features #

  • Read C2PA manifests from JPEG, PNG, TIFF, WebP, and DNG files
  • Write new manifests with actions, ingredients, and custom assertions
  • Sign using PEM-based keys (development) or platform keystores (production)
  • iOS Keychain and Android Keystore signing support
  • Fluent builder API for constructing manifests
  • 40+ action factories covering the full C2PA and CAWG action vocabulary
  • AI/ML content tracking with digital source types and training-mining assertions
  • Built on c2pa-rs v0.75 — the same engine behind Adobe Content Authenticity

Platform Support #

Platform Read Write/Sign Platform Keystore
Android ✅ (Keystore)
iOS ✅ (Keychain)

Getting Started #

Prerequisites #

  • Flutter SDK ≥ 3.3.0 / Dart SDK ≥ 3.7.0
  • Rust toolchain (install via rustup)
  • iOS: rustup target add aarch64-apple-ios aarch64-apple-ios-sim
  • Android: rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android i686-linux-android

Installation #

dependencies:
  c2pa_flutter: ^0.1.0

Initialization #

Call C2pa.init() once at app startup before using any other API:

import 'package:c2pa_flutter/c2pa_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await C2pa.init();
  runApp(MyApp());
}

Usage #

Reading Manifests #

final reader = C2pa.reader();

// From a file path
final store = reader.readFromFile('/path/to/photo.jpg');

// From raw bytes
final store = reader.readFromBytes(bytes, mimeType: 'image/jpeg');

// From a URL
final store = await reader.readFromUrl('https://example.com/photo.jpg');

// Inspect the active manifest
final manifest = store?.active;
print(manifest?.title);            // "photo.jpg"
print(manifest?.claimGenerator);   // "c2pa-rs/0.75.19"
print(manifest?.signatureInfo?.issuer);  // "Adobe"
print(manifest?.signatureInfo?.alg);     // "Es256"

// Check actions
for (final action in manifest?.actions ?? []) {
  print('${action.action}: ${action.description}');
}

// Check for AI-generated content
if (manifest?.hasAiGeneratedContent ?? false) {
  print('This image contains AI-generated content');
}

Building and Signing Manifests #

// 1. Build a manifest
final manifest = ManifestBuilder(
  claimGenerator: 'MyApp/1.0',
  title: 'edited_photo.jpg',
  format: 'image/jpeg',
)
    .addAction(C2paActions.created(
      description: 'Captured with MyApp camera',
    ))
    .addAction(C2paActions.edited(
      description: 'Applied brightness filter',
    ))
    .build();

// 2. Create a signer (file-based for development)
final signer = FileSigner(
  privateKeyPem: keyPemBytes,
  certChainPem: certPemBytes,
  algorithm: SigningAlgorithm.es256,
);

// 3. Sign the image
final writer = C2pa.writer();
final signedBytes = await writer.sign(
  imageBytes: originalImageBytes,
  mimeType: 'image/jpeg',
  manifest: manifest,
  signer: signer,
);

Platform Keystore Signing (Production) #

For production apps, use the device's secure keystore instead of PEM files:

// iOS (Keychain) / Android (Keystore)
final signer = PlatformSigner(
  keyAlias: 'my_signing_key',
  certChainPem: certChainBytes,
  algorithm: SigningAlgorithm.es256,
);

final signedBytes = await writer.sign(
  imageBytes: imageBytes,
  mimeType: 'image/jpeg',
  manifest: manifest,
  signer: signer,
);

Action Factories #

The C2paActions class provides factories for all standard C2PA and CAWG actions:

// Common actions
C2paActions.created(description: 'Original capture')
C2paActions.edited(description: 'Cropped to 16:9')
C2paActions.filtered(description: 'Applied sepia tone')
C2paActions.resized(description: 'Scaled to 1080p')

// AI/ML actions
C2paActions.aiGenerated(
  description: 'Generated by Stable Diffusion',
  sourceType: DigitalSourceType.trainedAlgorithmicMedia,
)
C2paActions.promptBasedEdit(description: 'AI background replacement')

// Publishing actions
C2paActions.published(description: 'Posted to social media')
C2paActions.redacted(reason: 'Removed location metadata')

Supported File Formats #

// Check MIME type for any extension
final mime = C2paReader.mimeTypeForExtension('jpg');  // "image/jpeg"

Supported: JPEG, PNG, TIFF, WebP, DNG, and camera RAW formats (ARW, CR2, CR3, NEF, NRW, RAF, RW2, ORF, PEF, SRW).

Architecture #

c2pa_flutter/
├── lib/
│   ├── c2pa_flutter.dart          # Library barrel file
│   ├── c2pa.dart                  # C2pa singleton (init, reader, writer)
│   ├── domain/
│   │   ├── entities/              # Manifest, Action, Ingredient, etc.
│   │   └── exceptions/            # C2paException hierarchy
│   └── src/
│       ├── reader/                # C2paReader
│       ├── writer/                # C2paWriter, ManifestBuilder, signers
│       └── rust/                  # Generated FFI bindings
├── rust/                          # c2pa-rs Rust wrapper
│   ├── Cargo.toml                 # c2pa = "0.75"
│   └── src/api/                   # reader.rs, writer.rs
├── android/                       # Android Keystore signer
├── ios/                           # iOS Keychain signer
└── example/                       # Full demo app with read/write/edit

The plugin uses Flutter Rust Bridge v2.11.1 to call into c2pa-rs v0.75 via FFI. The Rust library is compiled automatically by Cargokit during the Flutter build process — no manual Rust builds required.

Example App #

The example/ directory contains a full demo app with two tabs:

  • Read tab — cycles through 5 bundled C2PA test images, each with a different manifest structure (chained, redacted, ingredient references, etc.)
  • Write tab — signs an image with a test certificate, then lets you adjust brightness with a slider and re-sign to demonstrate provenance tracking with recorded edit actions

Run the example:

cd example
flutter run

c2pa-rs Compatibility #

This plugin uses c2pa-rs v0.75, which introduced some JSON format changes from earlier versions. The Dart parser handles both old and new formats:

Field Pre-0.74 v0.75+
Claim generator claim_generator (string) claim_generator_info (array)
Actions label c2pa.actions c2pa.actions.v2

Contributing #

Contributions are welcome! Please see the GitHub repository for issues and pull requests.

License #

MIT License — see LICENSE for details.

Acknowledgments #

0
likes
160
points
80
downloads

Publisher

unverified uploader

Weekly Downloads

Combined read/write C2PA Flutter plugin with manifest signing and certificate management. Uses the official c2pa-rs Rust library via FFI.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

equatable, flutter, flutter_rust_bridge, http, plugin_platform_interface

More

Packages that depend on c2pa_flutter

Packages that implement c2pa_flutter