
HMAC-SHA256 signed software licensing for Delphi 10.3 Rio and later (VCL / Windows).
Why 2.0?
Version 1.x used fake encryption (EncodeString) and ContainsStr checks, which were easy to spoof and brittle with dates. 2.0 signs a JSON payload with HMAC-SHA256, and adds optional hardware binding, feature flags, license types, and a drop-in TDFLicencer component.
Version 1.x keys are not compatible with 2.0.
Features
Signed license token:
DFL2..Trial / Standard / Professional / Enterprise / Perpetual
Expiry date or never-expires
Grace period after expiry
Feature flags (
reports,export, ...)Optional hardware binding (machine ID)
Application version range (
MinVersion/MaxVersion)Storage in
license.licor.iniPalette component: TDFLicencer (
DF Licencer)Runtime + design-time packages (Win32 design-time, Win32/Win64 runtime)
Package install
Open
packages\DFLicencer.groupprojin Delphi 10.3+.Build DFLicencer (runtime), then DFLicencerDesign.
Install the design-time package: Component > Install Packages > Add and select
bin\Win32\Release\DFLicencerDesign.bpl(output folder may differ).TDFLicencerappears on the Tool Palette under DF Licencer.
Alternatively, add the units from source\ to your project. The demos compile this way; installing the BPL is optional.
Quick start
Use the same ProductId and SecretKey in the generator and in your application. The secret is compiled into the binary — use your own long random value in production.
uses
DFLicencer.Component, DFLicencer.Types;procedure TFormMain.FormCreate(Sender: TObject);
begin
DFLicencer1.ProductId := 'com.mycompany.myapp';
DFLicencer1.SecretKey := 'your-long-random-secret';
DFLicencer1.LicenseFile := 'license.lic';
DFLicencer1.AppVersion := '2.0.0';
DFLicencer1.HardwareBinding := False;
DFLicencer1.GraceDays := 3; DFLicencer1.CheckLicense;
if not DFLicencer1.IsLicensed then
begin
ShowMessage(DFLicencer1.StatusText);
Application.Terminate;
Exit;
end; if DFLicencer1.HasFeature('export') then
EnableExport;
end;Generate a key (in your generator / sales tool):
uses
DFLicencer.Core, DFLicencer.Types;var
Info: TDFLicenseInfo;
Key: string;
begin
Info.Clear;
Info.ProductId := 'com.mycompany.myapp';
Info.ProductName := 'My App';
Info.CustomerName := 'Acme Ltd';
Info.LicenseType := ltProfessional;
Info.IssuedAt := Date;
Info.ExpiresAt := EncodeDate(2027, 12, 31);
Info.Features := 'reports;export;api';
Info.Seats := 5;
Key := TDFLicenseCodec.Generate(Info, 'your-long-random-secret');
end;Activate in the customer app:
DFLicencer1.Activate(PastedKey);If the key is valid, it is saved to LicenseFile.
TDFLicencer
PropertyDescriptionProductIdProduct identity the license is bound toSecretKeyHMAC secret (must match the generator)LicenseFilelicense.lic or .iniAppVersionUsed for min/max version checksHardwareBindingWhen True, the license is locked to this machineGraceDaysExtra days after expiryAutoCheckValidate in Loaded (skipped at design-time)OnStatusStatus callback
Methods: CheckLicense, Activate, HasFeature, DaysRemaining, MachineId, IsLicensed, StatusText.
Demos
demo\Generator— license generatordemo\SampleApp— paste a key and activate
Sample Product ID (both demos): com.delphifan.sample
Sample secret: change-this-secret-in-production
Requirements
RAD Studio / Delphi 10.3 Rio or later
Windows (machine ID is Win32/Win64)
