KeyNub ships as one core library with a stable C ABI, with thin bindings layered on top. That matters more than a long language list: the cryptography, the USB transport and the protocol live in one tested place, and a binding is a translation layer rather than a reimplementation. When we fix something, every language gets the fix.
The bindings, the samples and the C ABI header are Apache-2.0 licensed and published, so you can read exactly what your integration will look like before you buy: the API, the error handling and a working sample in your language. That is possible because the protection is the ECC key inside the dongle’s secure element, not secrecy about how you talk to it.
For the hardware the library talks to — USB identifiers, report size and throughput, the secure element, record and counter limits — see the one-page datasheet (PDF).
Supported languages
| Language | Binding | Sample | Package |
|---|---|---|---|
| C | the core library and its header directly | samples/c | |
| C++ | header-only RAII wrapper, C++11 | samples/cpp | |
| C# | one .NET assembly, KeyNub.LicenseDongle | samples/csharp | |
| VB.NET | the same .NET assembly | samples/vbnet | |
| F# | the same .NET assembly | samples/fsharp | |
| Python | ctypes, plus the licd-tool CLI | samples/python | |
| Java | JNA, Java 17+ | samples/java | |
| Delphi / Free Pascal | a Pascal unit over the C ABI | samples/delphi | — |
| Visual Basic 6 | COM object KeyNub.Dongle | samples/vb6 | — |
| twinBASIC | the same COM object, 32- or 64-bit | samples/twinbasic | — |
| Excel / VBA / Access | Declare PtrSafe module, or COM | samples/vba | — |
| MATLAB / Simulink | MEX gateway, incl. MATLAB Coder output | samples/matlab, samples/simulink | |
| LabVIEW | VI library (LabVIEW 2026) over Call Library Function nodes | samples/labview | — |
| Node.js / Electron | @keynub/licdongle, prebuilt natives | samples/nodejs | |
| Go (Golang) | cgo, errors.Is sentinels | samples/go | |
| Rust | keynub-licdongle, no dependencies | samples/rust | |
| Ruby | stdlib Fiddle, no gems | samples/ruby | |
| PHP | the bundled FFI extension | samples/php | |
| Perl | FFI::Platypus | samples/perl | — |
| Lua | LuaJIT FFI, one file | samples/lua | |
| Fortran | Fortran 2003 iso_c_binding | samples/fortran | — |
| COBOL | a copybook over the flat API | samples/cobol | — |
| Zig | @cImport compiles the real header | samples/zig | — |
| Julia | ccall, no packages | samples/julia | — |
| Nim | importc over dynlib | samples/nim |
Platforms and architectures
The repository carries prebuilt native libraries for all of these, each listed with its SHA-256 in natives/MANIFEST.txt:
| Platform | Architectures |
|---|---|
| Windows | x64, 32-bit (x86), ARM64 |
| Linux | x86_64, ARM64 (aarch64) |
| macOS | one universal binary — Apple Silicon and Intel |
There is no driver on any of them — the dongle is a standard USB HID device. On Linux you install a one-line udev rule, which grants your user access to the device; it is a permission rule, not a driver. On macOS the vendor-defined usage page means no Input Monitoring prompt.
One thing worth knowing when you pick a library: match the architecture of your host process, not of the machine. A 32-bit application on 64-bit Windows needs the x86 build, and on Windows on ARM a native ARM64 application needs the ARM64 build while an x64 application running under emulation needs the x64 one. It is the single most common integration problem, and none of its symptoms say so.
Every binding is built and tested on Windows, Linux and macOS, and every language on this page ships a working sample you can run as-is.
Where you put the check matters more than which language you use
The most common mistake in dongle integration is asking a yes/no question:
If IsGenuine() Then
unlockEverything()
End If
One patched jump instruction defeats that, in any language. A dongle cannot stop someone editing your binary — so do not give them a single branch to edit. Instead, make the program need something only the dongle can produce:
coefficients = dongle.AppDecrypt(blobShippedWithYourInstaller)
Now the license check is not a gate in front of the feature; it is the feature’s input. Remove the dongle and the code does not run wrong, it has nothing to run on. The SDK documents this pattern for every binding, and the MATLAB and Simulink samples demonstrate it on real plant coefficients.
What a typical integration looks like
- Enumerate and open the dongle (no driver install — it is a HID device)
- Verify it is genuine, against the KeyNub root CA built into the SDK
- Open an encrypted session
- Read your license record, or decrypt data your application needs
- Ship
Most integrations are a day’s work. If yours is not, tell us what got in the way — that is the kind of bug report we act on.
Looking for your industry rather than your language? See where a hardware license dongle fits — thirteen industries from CAM and CNC to medical, broadcast and machine vision.