c2pa_flutter 0.1.0
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.
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 #
- c2pa-rs by the Content Authenticity Initiative
- Flutter Rust Bridge for seamless Dart-Rust FFI
- C2PA Specification by the Coalition for Content Provenance and Authenticity