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).
Switching from CodeMeter or Sentinel HL? Those two pages put KeyNub beside each, fact by fact, and map the concepts (containers, feature codes, runtime) to the SDK’s records, sessions and library.
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 | |
| PowerShell | module KeyNub.LicenseDongle, Windows PowerShell 5.1 and PowerShell 7 | samples/powershell | |
| Python | ctypes, plus the licd-tool CLI | samples/python | |
| Java | JNA, Java 17+ | samples/java | |
| Clojure | com.keynub/keynub-licdongle-clj, over the Java binding | samples/clojure | |
| Scala | com.keynub:keynub-licdongle-scala_3 on Maven Central, Scala 3 over the Java binding | samples/scala | |
| Kotlin | com.keynub:keynub-licdongle-kotlin on Maven Central, Kotlin Multiplatform over the flat API | samples/kotlin | |
| Groovy | the Java binding com.keynub:keynub-licdongle, through @Grab | samples/groovy | — |
| 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 | |
| Wolfram Language | paclet over ForeignFunctionLoad, no LibraryLink shim | samples/wolfram | |
| LabVIEW | VI library (LabVIEW 2026) over Call Library Function nodes | samples/labview | |
| Node.js / Electron | @keynub/licdongle, prebuilt natives | samples/nodejs | |
| Deno | @keynub/licdongle on JSR, Deno.dlopen over the flat API | samples/deno | |
| 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 | — |
| Ada | Alire crate keynub_licdongle, library loaded at run time | samples/ada | |
| Zig | @cImport compiles the real header | samples/zig | |
| Swift | SwiftPM package at the repository root, library loaded at run time | samples/swift | |
| Dart / Flutter | keynub_licdongle on pub.dev, pure dart:ffi | samples/dart | |
| Julia | ccall, no packages | samples/julia | |
| R | CRAN package KeyNubLicDongle, C layer compiled at install | samples/r | |
| Nim | importc over dynlib | samples/nim | |
| Haskell | keynub-licdongle on Hackage, pure Haskell over the flat API | samples/haskell | |
| OCaml | keynub-licdongle on opam, ctypes-foreign over the flat API | samples/ocaml | |
| Elixir | keynub_licdongle on Hex, a small NIF over the flat API | samples/elixir | |
| Gleam | keynub_licdongle_gleam on Hex, typed Gleam over the Elixir package | samples/gleam | |
| D | keynub-licdongle on DUB, extern(C) over the flat API, nothing linked | samples/d | |
| Crystal | keynub_licdongle shard, function pointers over the flat API, nothing linked | samples/crystal | |
| Tcl | keynub_licdongle, pure Tcl over cffi and the flat API, nothing compiled | samples/tcl | |
| Raku | KeyNub::LicDongle in the zef ecosystem, NativeCall over the flat API | samples/raku | |
| Racket | keynub-licdongle on pkgs.racket-lang.org, ffi/unsafe over the flat API | samples/racket | |
| Common Lisp | ASDF system keynub-licdongle, CFFI over the flat API, nothing linked | samples/common-lisp | |
| SWI-Prolog | pack keynub_licdongle, a foreign module over the flat API, nothing linked | samples/prolog | |
| V | module keynub_licdongle, the dl module over the flat API, nothing linked | samples/v | |
| Odin | package keynub_licdongle, core:dynlib over the flat API, nothing linked | samples/odin | — |
Command-Line Tool
licd-tool is one executable with the core library built in: list and inspect dongles, verify them, read and write records, read and increment counters, and encrypt data that only a dongle can decrypt, from a script or a terminal. On Windows, choco install keynub-licd-tool installs the signed build for the machine’s architecture; the same builds are in the repository’s natives/ folder, and elsewhere it builds with CMake. pip install keynub-licdongle brings a licd-tool with the same commands.
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.
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 language on this page ships a working sample you can run as-is, and every binding comes with a stand-in test that exercises every call without a dongle.
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.