yubikey_flutter

Pub Platform License: MIT

YubiKey Flutter demo

Flutter plugin for YubiKey authentication, built on top of the official Yubico YubiKit Android SDK.

Supports:

  • OTP — read Yubico OTP via NFC tap
  • OATH TOTP/HOTP — list credentials and calculate codes
  • FIDO2 / WebAuthn — hardware-backed passkey registration and authentication
  • HMAC-SHA1 Challenge-Response — hardware-bound key derivation (e.g. for encrypting local data with a YubiKey-backed secret)

Unlike other community packages, this plugin wraps the official yubikit-android SDK directly, ensuring full protocol support and long-term compatibility.


Platform support

Android iOS
🔜 Roadmap

Installation

dependencies:
  yubikey_flutter: ^0.1.0

Android permissions

Add to your AndroidManifest.xml:

<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="false" />

Usage

Check NFC availability

final yubikey = YubikeyPlugin();

final supported = await yubikey.isNfcSupported();
final enabled   = await yubikey.isNfcEnabled();

Listen for YubiKey connection events

yubikey.onYubikeyConnected.listen((info) {
  print('Connected: ${info.deviceName} (${info.connectionType})');
  print('Serial: ${info.serialNumber}');
  print('Firmware: ${info.firmwareVersion}');
});

Read OTP

try {
  final result = await yubikey.readOtp(timeout: 30);
  print('OTP: ${result.otp}');
} on YubikeyTimeoutException {
  print('No YubiKey detected within timeout');
} on YubikeyException catch (e) {
  print('Error ${e.code}: ${e.message}');
}

OATH — list credentials and calculate codes

// List all credentials stored on the YubiKey
final credentials = await yubikey.listOathCredentials();
for (final cred in credentials) {
  print('${cred.displayName} (${cred.oathType.name})');
}

// Calculate all codes in a single NFC tap
final codes = await yubikey.calculateAllOathCodes();
for (final code in codes) {
  print('${code.credentialId}: ${code.code} (expires in ${code.remainingSeconds}s)');
}

// Calculate code for a specific credential
final code = await yubikey.calculateOathCode(credentials.first.id);
print('Code: ${code.code}');

Challenge-Response (HMAC-SHA1)

import 'dart:typed_data';

// Send a challenge to the YubiKey and get the HMAC-SHA1 response.
// Useful for key derivation (e.g., encrypting local data with a hardware-bound key).
final challenge = Uint8List.fromList(List.generate(32, (i) => i)); // your challenge bytes
final responseHex = await yubikey.challengeResponse(
  challenge: challenge,
  slot: 2, // default: Slot 2
);
print('HMAC response: $responseHex'); // 40-char hex string

FIDO2 — registration

// Challenge must come from your server
final reg = await yubikey.fido2Register(
  rpId:      'example.com',
  rpName:    'My App',
  userId:    'user-unique-id',
  userName:  'user@example.com',
  challenge: serverChallenge, // base64url encoded
);

// Send to your server for verification:
print('Credential ID: ${reg.credentialId}');
print('Attestation:   ${reg.attestationObject}');

FIDO2 — authentication

final assertion = await yubikey.fido2Authenticate(
  rpId:               'example.com',
  challenge:          serverChallenge, // base64url encoded
  allowCredentialIds: [registeredCredentialId],
);

// Send to your server for verification:
print('Signature: ${assertion.signature}');

Error handling

All methods throw typed subclasses of YubikeyException:

Exception When
YubikeyNfcDisabledException NFC is off in device settings
YubikeyNfcNotSupportedException Device has no NFC hardware
YubikeyTimeoutException No YubiKey detected within timeout
YubikeyCancelledException Operation cancelled
YubikeyInvalidPinException Wrong PIN (includes retriesRemaining)
YubikeyPinLockedException PIN locked after too many attempts
YubikeyNoCredentialsException No credentials found on device

How it works

This plugin uses Flutter platform channels to bridge the Dart layer with the native Android Kotlin layer, where yubikit-android handles all YubiKey communication over NFC.

Flutter (Dart) ──► MethodChannel ──► Kotlin ──► yubikit-android ──► YubiKey

Contributing

Pull requests welcome. This plugin is maintained by Luckysistemi.


License

MIT — see LICENSE

Libraries

yubikey_flutter
YubiKey Flutter Plugin Official YubiKit Android SDK wrapper for Flutter.