NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #2007 most downloaded on pub.dev
Hardware-backed biometric authentication for Flutter (Android, iOS, macOS, Windows). Create cryptographic signatures using Secure Enclave, StrongBox, and Windows Hello.
Last release 8 days ago
30 Sep 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 59 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
4 years old
64 releases · first in 2023
Optional key attestation. New CreateKeysConfig.attestationMode decides what createKeys does when attestationChallenge is set but the key can't be atte
CreateKeysConfig.attestationMode decides what createKeys does when attestationChallenge is set but the key can't be attested:
enforceOnChallenge (default): fails, as in 13.1.0.enforceOnChallengeIfSupported: creates an unattested key when the device or platform can't attest keys (notSupported, including iOS, macOS and Windows), but still fails on transient keystore failures (notAvailable). Android 7–12 report transient failures as notSupported, so this mode falls back there.preferred: creates an unattested key on any attestation failure.disabled: ignores the challenge.KeyCreationResult.attestationErrorCode (notSupported or notAvailable) and attestationError say why. Every mode except disabled still returns invalidInput for an empty or over-128-byte challenge.attestationChallenge now returns invalidInput on every platform. An empty or over-128-byte challenge used to return notSupported on Android 6 (API 23), iOS, macOS and Windows. The challenge length is now checked first, in every mode except disabled.One column per quarter.
Android hardware key attestation. Fixes #69.
CreateKeysConfig.attestationChallenge (Uint8List, 1–128 bytes, Android 7.0+). When set, createKeys passes it to KeyGenParameterSpec.Builder.setAttestationChallenge, and returns the keystore's X.509 attestation chain for the new signing key in the new KeyCreationResult.attestationCertificateChain (List<Uint8List>, DER, leaf first). The plugin doesn't parse the chain; verify it on your server — see the README's "Hardware Key Attestation" section.getKeyInfo returns the same chain in the new KeyInfo.attestationCertificateChain for keys created with a challenge. The chain is recognised by the key attestation extension (OID 1.3.6.1.4.1.11129.2.1.17) on its leaf; unattested keys report null.createKeys fails instead of returning an unattested key:
invalidInput for an empty or over-128-byte challenge, and notSupported on Android 6 (API 23). Both are checked before any existing key is touched.notSupported when the keystore can't attest the key, and notAvailable for a transient keystore failure (e.g. attestation keys not provisioned yet — retry later with a fresh challenge). The transient case is detected on Android 13+; older versions report notSupported. As with any key-creation failure, the existing key under the alias has already been deleted by then; use failIfExists or a fresh alias to keep it.attestationSecurityLevel shows which one produced the key.ecdsa + enableDecryption) only the keystore EC signing key is attested; the software decryption key cannot be.attestationChallenge returns notSupported without touching existing keys, instead of being ignored like other platform-specific fields — ignoring it would hand back an unattested key the caller believes is attested. Apple has no public API to attest an individual Secure Enclave key, and Windows attestation is not implemented.BiometricError values.Android: a failed hybrid-mode createKeys could leave a signing-only key behind. If the AES master key failed to generate after the EC signing key was created (ecdsa + enableDecryption), createKeys returned an error but left the EC key under the alias, so getKeyInfo reported a non-hybrid EC key there (with an attestation chain, if a challenge was set). The partially created keys are now deleted before the error is returned, as they already were for failures later in key creation, and also if the Flutter engine detaches while the keys are being generated.
Android: a missing key was reported as unknown instead of keyNotFound. Signing or decrypting with an alias that has no key (or whose hybrid-mode decryption key is gone) threw a generic exception that fell through to unknown. These cases now return keyNotFound, as they already did on iOS, macOS and Windows.
iOS/macOS: getKeyInfo couldn't return the public key of an RSA key, and reported it as hybrid. In RSA mode the RSA private key is stored wrapped by the Secure Enclave key, and its public key wasn't persisted, so getKeyInfo returned publicKey: null (reading it back would have needed a prompt). The public key is now stored at creation, so getKeyInfo returns the same key createKeys did. Keys created by earlier versions store it on their next successful sign or decrypt.
isHybridMode is now false for these keys in both createKeys (previously unset) and getKeyInfo (previously true). The same RSA key signs and decrypts, so this isn't hybrid mode (separate signing and decryption keys) as the field is defined, and it now matches Android's RSA mode. Encrypt RSA-OAEP payloads against publicKey; the README previously said decryptingPublicKey, which is null for these keys.iOS/macOS: a key invalidated by a biometric enrollment change was never reported as keyInvalidated. Signing or decrypting with a .biometryCurrentSet key after a face/fingerprint was enrolled or removed surfaced whatever the Secure Enclave returned, usually unknown or authenticationFailed, so apps couldn't tell that the key had to be re-created. The plugin now compares the enrollment snapshot saved at key creation before prompting, and returns keyInvalidated without showing a prompt, as Android does. getKeyInfo(checkValidity: true) uses the same check, which also fixes two false reports of an invalid key:
useDeviceCredentials: true uses .userPresence, which the device passcode can always satisfy, so an enrollment change never invalidates it. It was nevertheless recorded as invalidatable and reported isValid: false after one. Such keys are no longer recorded or reported as invalidatable..biometryAny or .userPresence), no longer report isValid: false.createSignature and decrypt now reject an empty payload before any prompt.
createSignature signed an empty payload. createSignature(payload: '') went on to sign zero bytes, where Android and Windows return invalidInput. It now returns invalidInput ("Payload is required") before any key lookup or prompt, as createSignatureFromBytes already did. Android still also rejects a whitespace-only string; iOS, macOS and Windows sign it.decrypt checked the payload only after accessing the key, in RSA mode after the user had authenticated. An empty or whitespace-only payload then failed with unknown or invalidInput ("Invalid payload"), depending on the format. Both now return invalidInput ("Payload is required") before any key lookup or prompt, as on Android.decrypt returned unknown for an empty payload when no activity was in the foreground, because it checked for the activity first. It now checks the payload first, as createSignature does.decrypt is unchanged: it returns notAvailable, since Windows doesn't support decryption.iOS/macOS: RSA-mode decrypt could return garbage as a successful result. When RSA-OAEP decryption failed, decrypt fell back to PKCS#1 v1.5, for ciphertext made for keys created before v11.0.0. Current iOS and macOS releases decrypt PKCS#1 v1.5 with implicit rejection: invalid ciphertext yields pseudorandom bytes instead of an error. So corrupted or tampered OAEP ciphertext fell through to the fallback, and roughly once in 100 to 300 attempts decrypt returned success with a meaningless, often empty, string (measured on iOS 26.5, iOS 27 and macOS 27).
unknown.decrypt reported a malformed payload only after the user had authenticated. In RSA mode on iOS/macOS, and for every key that needs authentication on Android, the payload was decoded only after the prompt. It's now decoded first: input that isn't valid for payloadFormat returns invalidInput before any key access or prompt. So does input that can't be an ECIES payload (too short, or not starting with an uncompressed ephemeral key) for Android hybrid keys and iOS/macOS EC keys, once the key checks pass. It used to fail only later, sometimes with unknown.
A!Q== decoded as AQ== and .... as nothing.README: the ECIES section said no per-platform branch was needed. It is: Android derives a 16-byte AES key and a 12-byte GCM IV from the shared secret with empty shared info, while Apple's eciesEncryptionStandardX963SHA256AESGCM uses the ephemeral public key as shared info, derives only the key, and uses a 16-byte zero IV. A payload encrypted for one platform fails on the other. "Encrypting a payload" now gives both, and notes that decrypt returns UTF-8 text.
example/ is now an API Explorer covering every method, option, format and error code, and the scenario apps (passwordless_login, banking_app, and secure_vault, formerly document_signer) verify signatures and Android attestation chains in an in-process mock server instead of only checking that a signature is non-empty.post_install. Flutter 3.47 and later do this for you; on older versions, an app that builds with Xcode 27 through CocoaPods needs the same step.Bump version to 12.0.1 and fix Android prompt customization and ProGuard rules by @chamodanethra in #68
createSignatureFromBytes API method across Dart and all supported native platforms by @chamodanethra in #73Full Changelog: biometric_signature-v12.0.0...biometric_signature-v13.0.0
BiometricError causes: authenticationFailed (an attempt that didn't succeed — unrecognised biometric or the platform couldn't process it; retrying usually works) and notInteractive (the prompt couldn't be shown, e.g. the app is backgrounded). Whether to retry or degrade is left to the consumer.unknown are now classified more precisely:
authenticationFailed and the observed -1000 code → authenticationFailed; notInteractive → notInteractive; app-cancel → systemCanceled; -1018 and keychain errSecInteractionNotAllowed → notAvailable; keychain errSecAuthFailed → authenticationFailed.UNABLE_TO_PROCESS (2) and "key user not authenticated" → authenticationFailed. Pruned keystore ops and TIMEOUT (3) stay unknown with the enriched message; the retry-once for pruned ops still applies.switches on BiometricError.CreateKeysConfig.setInvalidatedByBiometricEnrollment now defaults to true on every platform. The default diverged per platform: Android used true, iOS/macOS used false, so the same createKeys call produced keys with different lifetimes on each platform. All platforms now default to true, matching AndroidKeyStore's own default for auth-bound keys (mInvalidatedByBiometricEnrollment = true) and the flag's documented security intent. Fixes #70.
createKeys call that leaves the flag unset now produces a .biometryCurrentSet Secure Enclave key instead of .biometryAny, so the key is permanently invalidated when a face/fingerprint is enrolled or removed and the app must create a new key and re-enroll its public key. Pass setInvalidatedByBiometricEnrollment: false to keep the previous behaviour. Use getKeyInfo(checkValidity: true) to detect an invalidated key before signing.requireAuthentication is false — a key created without a user-authentication constraint carries no biometry binding, so it is neither invalidated nor reported as invalid on enrollment changes.Android: an explicit setInvalidatedByBiometricEnrollment: false was silently ignored. KeyManager.configureInvalidation only ever called KeyGenParameterSpec.Builder.setInvalidatedByBiometricEnrollment(true) and skipped the call entirely for false. Since AndroidKeyStore's own default is true, opting out left the platform default in place and the key was still permanently invalidated on the next biometric enrollment — with no error to indicate the request had been dropped. The setter is now always called with the caller's value (API 24+; API 23 has no setter and always invalidates).
Android: the plugin failed to configure under Android Gradle Plugin 9. AGP 9 ships "built-in Kotlin" — it supplies the Kotlin toolchain itself — and rejects kotlin-android with "The 'org.jetbrains.kotlin.android' plugin is no longer required for Kotlin support since AGP 9.0", so android/build.gradle aborted at apply plugin: "kotlin-android". AGP 9 also removed kotlinOptions {} from the Android extension. The plugin now applies kotlin-android only when AGP has not already registered a kotlin extension, and sets the JVM target through kotlin { compilerOptions { jvmTarget } }, which works on both toolchains. Verified building on AGP 8.9.1/Gradle 8.12/Flutter 3.24.5, and on AGP 9.3.1/Gradle 9.6.1/Flutter 3.44.8 with android.builtInKotlin both true (the AGP 9 default) and false (what Flutter's AGP 9 migrator writes). Fixes #78.
compileSdk stays at 35: a library's compileSdk is a floor for its consumers, not a ceiling, so apps on compileSdk 36/37 already build against it. Raising it would force every consuming app to raise theirs.WARNING: ... plugins that apply Kotlin Gradle Plugin (KGP): biometric_signature. It is a text match on this plugin's build file, not a reflection of what runs, and is safe to ignore — see the README.lintOptions {} (deprecated) replaced with the equivalent lint {} block.
AndroidKeyStore defaults to SHA-1 for the MGF1 digest in RSA-OAEP, even when SHA-256 is used as the main digest. To prevent future platform changes from making existing ciphertexts undecryptable, this change explicitly pins the RSA-OAEP parameters.
Merge pull request #73 from chamodanethra/feature/createSignatureFrom…
Merge pull request #73 from chamodanethra/feature/createSignatureFrom…
unknown (iOS/macOS). createSignature previously hard-coded code: .unknown on every SecKeyCreateSignature failure, discarding the real cause. classifySigningError now walks the CFError's NSUnderlyingErrorKey chain and maps the first layer it recognises — LAErrorDomain via mapLAError, NSOSStatusErrorDomain (e.g. errSecUserCanceled / -128) via mapSecError — so a cancelled or unavailable signing prompt surfaces BiometricError.userCanceled / BiometricError.notAvailable regardless of whether the cancel arrives as the top-level CFError, an OSStatus layer, or a nested LAError (e.g. a localized "Authentifizierung abgebrochen." cancel). The "Signing Error: …" message is additionally enriched with the full domain:code chain (e.g. … [CryptoTokenKit:-4 -> com.apple.LocalAuthentication:-2]) so any still-unmapped failure is self-describing in logs. Both the RSA and EC signing paths are covered.UNKNOWN errors are no longer flattened to a constant string. ErrorMapper.safeErrorMessage used to collapse every unmapped failure to "Biometric operation failed", throwing away both the numeric BiometricPrompt code and the original errString. The UNKNOWN branch now appends whatever context is available, e.g. "Biometric operation failed (code=3 msg=…)", keeping failures diagnosable in logs without an API/schema change.Non-interactive (no user authentication) keys via CreateKeysConfig.requireAuthentication. Defaults to true (existing behaviour). When set to false, the key pair is created without a use-time user-authentication constraint and can be used to sign/decrypt without any biometric or device-credential prompt — useful for a device-bound key that lives alongside an interactive (biometric) key under a different keyAlias.
setUserAuthenticationRequired(true) (and without per-operation auth / invalidation), and createSignature/decrypt detect the key's KeyInfo.isUserAuthenticationRequired and skip the BiometricPrompt entirely..privateKeyUsage access control (no .biometryAny/.userPresence) and kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, so signing/decryption never prompt while the device is unlocked.New createSignatureFromBytes method: Introduced a high-level API to request biometric signatures directly over raw binary payloads (Uint8List), supporting secure challenge-response and transaction validation patterns across Android, iOS/macOS and Windows.
Binary Challenge-Response Demo Card: Added a demonstration card inside the example app showcasing the complete secure random nonce generation and direct signing workflow.
Android: three more BiometricPrompt error codes are classified. ErrorMapper.mapToBiometricError now maps ERROR_NO_BIOMETRICS (11) → notEnrolled, ERROR_HW_NOT_PRESENT (12) → notAvailable, and ERROR_SECURITY_UPDATE_REQUIRED (15) → securityUpdateRequired. ERROR_TIMEOUT (3) and ERROR_VENDOR (8) intentionally remain enriched-UNKNOWN so their volume can be observed before assigning a dedicated bucket.
Android: error-source markers. Failures now carry a short source tag so a "couldn't even show the prompt" failure isn't mistaken for a signing failure: [src=prompt cred=<allowDeviceCredentials>] for real onAuthenticationError callbacks, [src=availability] for canAuthenticate pre-checks, and [src=launch] for setup/launch failures (e.g. the host is not a FragmentActivity). CancellationException is passed through unchanged so coroutine cancellation semantics and its userCanceled classification are preserved.
prepareSignature() and held open across the entire BiometricPrompt interaction. While a device-credential (PIN/pattern) prompt is showing, the app is backgrounded and its operation has the lowest pruning resistance, so keystore2 can evict it (INVALID_OPERATION_HANDLE / "outcome: Pruned") whenever another operation needs a slot — which previously surfaced as a hard "Biometric operation failed". Since the key is intact, createSignature now detects this specific transient failure (ErrorMapper.isPrunedOperationError) and transparently re-runs begin → authenticate → sign once before giving up. Pruning is contention-based, not a timeout, so it can strike no matter how long the user takes on the credential screen.Merge pull request #68 from chamodanethra/fix/add-missing-parameters-…
Merge pull request #68 from chamodanethra/fix/add-missing-parameters-…
createKeys, createSignature, and decrypt. The Dart API and Pigeon schema have always exposed promptSubtitle, promptDescription, and cancelButtonText on CreateKeysConfig / CreateSignatureConfig / DecryptConfig, and the README documented them, but the Android plugin was silently dropping them — createKeys and decrypt hard-coded null, null, "Cancel" into the BiometricPrompt, and createSignature hard-coded null for the description. All three are now threaded through to BiometricPrompt.PromptInfo.Builder. Fixes #67.androidx.biometric.BiometricManager#getStrings(int) and BiometricManager$Strings#getButtonLabel() / getPromptMessage() / getSettingButtonLabel(), which are invoked via reflection by BiometricPromptHelper.detectBiometricTypes to disambiguate face/fingerprint/iris on devices that advertise multiple BIOMETRIC_STRONG modalities. Without these rules, R8 would rename or strip the methods in release builds and the label-matching path would silently fall back to feature-flag-only detection.Update iOS migration logic and relax platform SDK constraints by @chamodanethra in #66
Full Changelog: biometric_signature-v11.1.0...biometric_signature-v12.0.0
3.24.5 / Dart to 3.5.0. The plugin resolves on Flutter 3.24.5 with a small Android build-config override in the consuming app — Flutter 3.24.5's defaults (flutter.compileSdkVersion = 34, flutter.ndkVersion = "23.1.7779620", flutter.minSdkVersion = 21) are below what androidx.biometric:1.4.0-alpha05 and modern AndroidX plugins require. Set compileSdk = 35, ndkVersion = "27.0.12077973", and minSdk = 23 in your app's android/app/build.gradle.kts. See README → "Required Android build configuration" for the exact snippet.minSdk lowered to 23, the floor required by androidx.biometric for BiometricPrompt.compileSdk lowered to 35 (from 36). The plugin no longer requires Android SDK Platform 36 or AGP 8.9.1 — compileSdk = 35 and AGP 8.6.0 are sufficient.androidx.biometric:biometric downgraded from 1.4.0-alpha06 → 1.4.0-alpha05, which only requires compileSdk 35 and AGP 8.6.0. Plugin's buildscript classpath also dropped to AGP 8.6.0 to match.25.3.2 → ^25.3.2.shouldMigrate: true against an existing EC key no longer errors. Previously, setting shouldMigrate: true on CreateSignatureConfig / DecryptConfig against a v10+ EC-only key (no legacy v2.x RSA in the keychain) triggered a misfired migration that returned RSA private key not found in Keychain. The migration is now auto-detected from keychain state instead of a caller-supplied flag, so the misfire scenario is structurally unreachable. Fixes #65.androidx.biometric API for Fallback.CustomOption, Fallback.ICON_TYPE_*, and AuthenticationResult.CustomFallbackSelected only exists in 1.4.0-alpha06+, which forced compileSdk = 36. Removed entirely so the plugin can run on broader tooling.
BiometricFallbackOption class.BiometricError.fallbackSelected enum value.fallbackOptions field from CreateKeysConfig, CreateSignatureConfig, DecryptConfig, and SimplePromptConfig.selectedFallbackIndex and selectedFallbackText fields from SignatureResult, DecryptResult, and SimplePromptResult.shouldMigrate flag on CreateSignatureConfig and DecryptConfig. The iOS Secure Enclave migration from v2.x unwrapped RSA keys is now auto-detected (see Fixed above). Apps no longer need to opt in — and no longer can opt in incorrectly. Pigeon-bridged removal, so existing call sites that pass shouldMigrate: true or shouldMigrate: false will fail to compile until the parameter is dropped.BiometricFallbackOption to render Android 15+ custom fallback buttons, you now need to drive that fallback behaviour from your own UI (e.g. catch the negative-button cancel, then present a Flutter sheet listing the alternatives). The plugin's standard cancelButtonText and allowDeviceCredentials flow still work everywhere they did before.BiometricError.fallbackSelected or reading selectedFallback* fields, those code paths can be deleted — they will never fire from the new plugin version.shouldMigrate: line from any CreateSignatureConfig(...) / DecryptConfig(...) constructor calls. The plugin auto-detects whether a legacy v2.x RSA key exists and migrates it on the first sign/decrypt call when appropriate.returns whether we have a screen lock set and tries to infer if biometrics or credentials were used by @HannesGitH in #61
Full Changelog: biometric_signature-v11.0.2...biometric_signature-v11.1.0
isDeviceLockSet() API: New method on BiometricSignature to check whether a device-lock credential is configured. Android uses KeyguardManager.isDeviceSecure() (authoritative). iOS/macOS evaluate LAPolicy.deviceOwnerAuthentication; true means "set or indeterminate" — a stronger guarantee surfaces via the reactive BiometricError.passcodeNotSet during the next operation. Windows reports Windows Hello availability via KeyCredentialManager.IsSupportedAsync(), not a generic screen-lock state — see the dartdoc for details.AuthenticationType reporting: New AuthenticationType enum (credential, biometric, unknown) plus an authenticationType field on KeyCreationResult, SignatureResult, DecryptResult, and SimplePromptResult. Authoritative on Android (from BiometricPrompt.AuthenticationResult). Inferred on Apple platforms from the key's stored useDeviceCredentials flag and biometric hardware availability; returns .unknown when the stored flag is unavailable rather than falsely reporting .biometric. Always .unknown on Windows.BiometricError.passcodeNotSet: Dedicated error code for "device has no screen lock / passcode configured", distinct from notAvailable.authenticationType inference: The useDeviceCredentials flag is now persisted in the keychain at key-creation time and read during sign/decrypt, replacing the previous signing-time heuristic that could not produce an accurate result.DeviceCredentialsSetting keychain item is now created with kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, matching the lifetime of the Secure Enclave key it accompanies and keeping the flag device-local.ERROR_NO_DEVICE_CREDENTIAL (cause code 14) now maps to BiometricError.passcodeNotSet instead of BiometricError.notAvailable. Consumers that were pattern-matching on BiometricError.notAvailable to drive a "no screen lock" UX must update their switch statements to handle BiometricError.passcodeNotSet. This is a minor-version bump because the Dart API surface is unchanged; only the runtime error value differs.kLAErrorPasscodeNotSet now maps to BiometricError.passcodeNotSet instead of BiometricError.notAvailable. Same migration guidance as above.Add biometric fallback options, named key aliases, and backup password support by @chamodanethra in #60
Full Changelog: biometric_signature-v10.2.0...biometric_signature-v11.0.2
Add Swift Package Manager support for macOS with Package.swift .
Package.swift.PrivacyInfo.xcprivacy in the macOS target.pubspec.yaml, README.md, and podspecs.feat: add backup password support and custom biometric fallback for A…
feat: add backup password support and custom biometric fallback for A…
createKeys, createSignature, decrypt, deleteKeys, getKeyInfo, biometricKeyExists) now accept an optional keyAlias parameter, allowing apps to manage multiple independent key pairs (e.g., one for auth, one for payment signing).CreateKeysConfig.failIfExists prevents accidental key replacement. When true, createKeys() fails with BiometricError.keyAlreadyExists if a key with the specified alias already exists.deleteAllKeys() method removes all plugin-managed keys across all aliases.CreateKeysConfig, CreateSignatureConfig, DecryptConfig, SimplePromptConfig) now support fallbackOptions — a list of BiometricFallbackOption items that appear as custom buttons on the biometric prompt. When the user taps a fallback option, the result contains BiometricError.fallbackSelected with selectedFallbackIndex and selectedFallbackText.KEY_INVALIDATED Error Mapping: BiometricError.keyInvalidated is now correctly returned when keys have been invalidated by biometric enrollment changes on Android.CancellationException is always rethrown, preventing callbacks to a detached Flutter engine.BiometricPromptHelper, CryptoOperations, ErrorMapper, FileIOHelper, FormatUtils, KeyManager).#if os(macOS)) to support both platforms from a single source file.spm migration by @chamodanethra in #58
Full Changelog: biometric_signature-v10.1.0...biometric_signature-v10.2.0
Full Changelog : biometric_signature-v10.0.0...biometric_signature-v10.1.0
Full Changelog: biometric_signature-v10.0.0...biometric_signature-v10.1.0
Package.swift + Sources/<plugin_name>/.Breaking: Added new BiometricError enum values; consumers using exhaustive switches must handle the new cases(security update required, not supported,
BiometricError enum values; consumers using exhaustive switches must handle the new cases(security update required, not supported, system canceled, prompt error).simplePrompt() for lightweight biometric authentication without cryptographic operations.Reduced published package size by ~45%.
Package Optimization: Reduced published package size significantly:
assets/logo.png (1.0 MB) to assets/logo.jpeg (120 KB), reducing image size by ~90%.pubignore to exclude example applications (banking_app, document_signer, passwordless_login) from published packageFeature: Added "Biometric Decryption" section to README.md with a detailed lifecycle diagram (usecase-2.png) and process description.
README.md with a detailed lifecycle diagram (usecase-2.png) and process description.KeyCredentialManager usage, TPM backing, RSA-2048 constraints, and lack of decryption support.pubspec.yaml description to explicitly include supported platforms and Windows Hello.Breaking: Method signature changes:
Breaking: Method signature changes:
createKeys() now takes config, keyFormat, promptMessage parameterscreateSignature() now takes payload, config, signatureFormat, keyFormat, promptMessage parametersdecrypt() now takes payload, payloadFormat, config, promptMessage parametersMoved cross-platform parameters into unified config objects:
signatureType, enforceBiometric, setInvalidatedByBiometricEnrollment, useDeviceCredentials now in CreateKeysConfigKeyCreationResult: Contains publicKey, error, and code.SignatureResult: Contains signature, publicKey, error, and code.DecryptResult: Contains decryptedData, error, and code.BiometricAvailability: detailed availability status including enrolled biometric types and error reasons.BiometricError enum across all platforms.biometricAuthAvailable() now returns a BiometricAvailability object instead of a raw string.signature_options.dart, decryption_options.dart and old config classes.userCanceled, notEnrolled, lockedOut) instead of generic strings.getKeyInfo() method: Retrieve detailed information about existing biometric keys without creating a signature.
KeyInfo object with: exists, isValid, algorithm, keySize, isHybridMode, publicKey, decryptingPublicKey.checkValidity parameter to verify key hasn't been invalidated by biometric changes.keyFormat parameter to specify output format (base64, pem, hex).KeyInfo class: Exported via Pigeon for type-safe key metadata.biometricKeyExists() is now a convenience wrapper around getKeyInfo().Full macOS support for biometric authentication using Touch ID.
BiometricSignaturePlugin.swift.MacosConfig class for platform-specific configuration:
useDeviceCredentials: Enable device credentials (passcode) fallbacksignatureType: Support for both MacosSignatureType.RSA and MacosSignatureType.ECDSAbiometryCurrentSet: Bind keys to current Touch ID enrollment statepromptMessage parameter to createKeys() method across all platforms
enforceBiometric is true"Authenticate to create keys" for backward compatibility{bundleId}.eckey, {bundleId}.biometric_key, etc.SecKeyAlgorithm.eciesEncryptionStandardX963SHA256AESGCMLAContext.evaluatedPolicyDomainStatebiometryCurrentSet is true)BiometricSignaturePlatform to properly handle macOS-specific parametersECIES decryption on Android and iOS.
decrypt() on Android and iOS.enableDecryption option in AndroidConfig to generate RSA keys with decryption capability.Optimize iOS createKeys implementation.
Added enforceBiometric parameter to createKeys() method to require biometric authentication before generating the key-pair.
enforceBiometric parameter to createKeys() method to require biometric authentication before generating the key-pair.AndroidSignatureOptions.Upgraded Flutter from 3.32.8 to 3.35.7
Added an optional parameter to configure whether the key should be invalidated on new biometric enrollment when creating the key.
Nothing published for this version
Breaking: createKeys now returns a KeyCreationResult instead of a plain base64 string, enabling configurable output formats.
createKeys now returns a KeyCreationResult instead of a plain base64 string, enabling configurable output formats.createSignature returns a SignatureResult that includes both the formatted signature and public key metadata.KeyFormat support across Dart, Android, and iOS with BASE64, PEM, RAW (DER/bytes), and HEX representations.FormattedValue utilities.createSignatureFromLegacyOptions helper.Reverting back to previous iOS IPHONEOS_DEPLOYMENT_TARGET(12.0).
* Updating documentations. * Minor bug fixes.
* Fix formatting errors.
* Updating documentations.
Breaking: Replace the map-based createSignature API with typed SignatureOptions, plus platform-specific option classes.
createSignature API with typed SignatureOptions, plus platform-specific option classes.createSignatureFromLegacyOptions helper to ease migration from the legacy API.allowDeviceCredentials parsing so boolean values are honoured.shouldMigrate.The migrate path for iOS from 5.x is preserved.
* Suggesting a fix for issue.
Suggesting a fix for issue using Kotlin coroutines.
* fix dart formatting errors.
Upgrading Flutter from 3.27.2 to 3.32.8.
* Suggesting a fix for issue.
Upgrading Flutter from 3.27.0 to 3.27.2.
Feature - Allow Device Credentials as a fallback for biometric authentication.
Upgrading Flutter from 3.19.6 to 3.27.0
A bug fix for key user not authenticated android crash.
A bug fix for android KeyStoreException crash.
A bug fix in iOS createKeys() flow.
* ReadMe.md updates.
Feature Secure Enclave migration from Key Chain.
Secure Enclave integration in iOS.
Fix iOs issue: biometricKeyExists always false .
* Fix linting issues.
Feature Use StrongBox in compatible android devices.
fix Local Authentication bypass in iOS when calling createSignature().
fix Biometric portal not coming up in iOS simulators when calling createSignature().
A crash on Android devices below API level 28 was fixed.
Fixed a bug in createKeys() for iOS.
The plugin offers more flexibility for advanced use cases, such as handling different biometric modalities and customizing the signature generation pr
Android: Fixed the issue with the createSignature() method, ensuring it doesn't encode the payload to base64.
createSignature() method, ensuring it doesn't encode the payload to base64.createKeys() method to align with standard RSA key formats.Removes a redundant code push in Android native code.
Returns "biometric" for Android devices with multiple BIOMETRIC_STRONG options when called biometricAuthAvailable().
Consistent Platform error handling.
* improved documentation.
upgrading flutter sdk to 3.7.11.
* upgrading dependencies. * refactoring.
Your coding agent can read these notes before it upgrades. Set up the MCP server →