appplayer_secure_core
Pure-Dart security primitives. No Flutter dependency, so a server, CLI or test harness can depend on it directly.
Seven modules — SIGN · STORE · CRYPTO · TRUST · AUDIT · MAUTH ·
BIO — plus shared types and error. Domain-neutral: it defines no domain
enums and no business event types, so a caller brings its own.
| Module | Surface |
|---|---|
| SIGN | SignatureVerifier · DefaultSignatureVerifier |
| STORE | SecureStorage port · InMemorySecureStorage |
| CRYPTO | CryptoProvider · DefaultCryptoProvider · AtRestSealer · PassphraseSealer |
| TRUST | TrustChainValidator · InMemoryTrustChainValidator |
| AUDIT | AuditLogger · DefaultAuditLogger · local / remote sinks |
| MAUTH | MutualAuth · DefaultMutualAuth (ECDH X25519 + HKDF) |
| BIO | BiometricAdapter port · UnavailableBiometricAdapter |
Storage is a port
SecureStorage has no default implementation here, because every real one is
a platform binding. Pass InMemorySecureStorage in a test, your own
file-backed store on a server, or the OS keychain under Flutter — see below.
import 'package:appplayer_secure_core/appplayer_secure_core.dart';
final sealer = AtRestSealer(storage: InMemorySecureStorage());
final sealed = await sealer.sealBytes(plaintext, context: 'vault');
final opened = await sealer.openBytes(sealed, context: 'vault');
PassphraseSealer derives its key from a passphrase alone (PBKDF2-HMAC-SHA256
→ ChaCha20-Poly1305), so a sealed blob moves between machines — unlike
AtRestSealer, whose key is bound to the store it was created against.
Biometrics
UnavailableBiometricAdapter reports biometrics as unavailable and refuses
every authentication. That is the honest answer where there is no OS prompt; an
adapter that quietly succeeded would turn "no biometric available" into
"biometric passed".
Relationship to appplayer_secure
appplayer_secure depends on this package and re-exports it, adding what needs
Flutter: the OS keychain backend, the biometric prompt, the asset-loaded Root
CA registry, and the AppPlayerSecure facade that assembles them. A Flutter
host depends on that package alone and sees both halves; a headless one depends
on this package and never pulls the Flutter SDK into its graph.
License
MIT
Libraries
- appplayer_secure_core
- Pure-Dart security primitives.