Skip to content

Software License Dongle for Dart and Flutter

Dart reaches the dongle through dart:ffi, which is part of the language, and loads the native library at run time — so the package is pure Dart with no plugin glue and no build step, the same in a command-line program and in a Flutter desktop application on Windows, Linux or macOS. For a licensing component that is the right shape: nothing sits in the path of the check that a customer could substitute for something more agreeable.

pub.dev version badge

dart pub add keynub_licdongleCode language: Dart (dart)

Reading a License

import 'package:keynub_licdongle/keynub_licdongle.dart';

final ctx = Context();
final dongle = ctx.open();                  // first dongle, or ctx.open(serial: ...)
dongle.verifyGenuine();                     // throws unless genuine

final license = dongle.withSession((s) =>   // closed on every exit path
    s.readRecord('license'));

dongle.close();
ctx.close();Code language: Dart (dart)

What You Are Protecting

A Flutter application ships as an ahead-of-time snapshot, and a Dart command-line tool as a native executable. Both are readable enough for a determined person to find if (!dongle.isGenuine) exit(1) and remove it: one branch, one patch. Obfuscation only raises the effort.

What cannot be patched away is data the program needs and only the dongle can decrypt. Seal it once with a developer dongle, ship only the sealed form, and the program has no copy to fall back on:

// Weak -- one deleted line.
if (!dongle.isGenuine) exit(1);

// Strong -- the parameters only exist with the dongle present.
final parameters = session.appDecrypt(sealedBlobShippedWithTheApp);Code language: Dart (dart)

withSession closes the session even when an exception unwinds through it, so there is no cleanup path to forget. Failures are LicenseDongleErrors with a status (Status.noDevice, notGenuine, authRequired, …), so a catch branches on what happened.

Shipping the Native Library with a Dart or Flutter Application

The keynub_licdongle package on pub.dev uses dart:ffi and loads the core library at run time. In a clone of the SDK it finds natives/<platform>/ on its own; a shipped application names the library with LicDongleLibrary.path before the first call, or sets KEYNUB_LICDONGLE_LIBRARY.

For a Flutter desktop application, bundle the library with the platform build: the Windows and Linux runners take it as a CMake install target, macOS as a framework or dylib in the bundle, and the app sets LicDongleLibrary.path relative to Platform.resolvedExecutable. On Linux, install the udev rule from NATIVES.md once, so that ordinary users may open the device.

Questions Dart Developers Ask

Which Dart and Flutter Versions Does the Binding Support?

Dart SDK 3.3 and later, and the Flutter releases built on it, for Windows, Linux and macOS desktop applications.

Can a Flutter Desktop App Be Protected with a Hardware Dongle?

Yes. The dongle calls run in the Dart process through dart:ffi; the data the app needs ships sealed and is decrypted through the dongle at start.

Does a Dart Application Need Administrator Rights to Talk to the Dongle?

No, and no driver either: the dongle is a USB HID device that the operating systems handle with their built-in class drivers. On Linux, install the shipped udev rule once so that ordinary users may open it; without the rule the SDK reports access denied and names the cause in its error detail.

Does a Dart License Check Need an Internet Connection?

No. Verification is a local exchange between your program and the dongle over USB: the SDK checks the dongle’s certificate chain to KeyNub’s root and runs a live challenge-response. There is no activation server and no account, so the check works on air-gapped machines.

Who Can Read the License Records on a Dongle?

Anyone holding the dongle: a program opens a session and reads records, and can decrypt data sealed for that dongle. Writing records, erasing them and incrementing counters need your write key. What the dongle guarantees is that none of it is available without the dongle present.

Can a License Written from Dart Be Read by a Program in Another Language?

Yes. Every binding drives the same core library and the same dongle, and records and sealed data are language-neutral bytes. Your issuing tool can be written in one language and your product in another.

Code

Runnable sample: dart/bin/verify_and_read.dart. Binding source: bindings/dart. Both are Apache-2.0, in the public SDK repository; the prebuilt native libraries are in the repository’s natives/ folder, one per platform.

All supported languages · All industries · Buy a KeyNub · Ask us something