How to add licence keys with an HWID lock to a C++ Windows app
Add licence keys, a one-PC lock and a live kill switch to a native C++17 Windows program with the free PWF Auth client: two files on WinHTTP and Windows CNG, a sign-in, the heartbeat and moving a licence to a new PC
Native C++ programs are often the ones worth protecting most: tools, game utilities, plugins. The PWF Auth C++ client gives them licence keys, a lock to one PC and a kill switch, with no runtime to install. It is plain C++17 on Windows' own building blocks: WinHTTP for HTTPS, Windows CNG for the encryption, and nlohmann-json from vcpkg
Step 1: create the application
Sign in to your panel, open Applications and press New application. Give it a name: the app secret is made for you
Step 2: add the client to your project
Download the latest release and copy four files into your project:
PwfClient.handPwfClient.cpp: the client itselfServerPublicKey.h: the public key the client checks every server reply withProductionPolicy.h: the server addresses the client may talk to
Add nlohmann-json with vcpkg (the sample project's vcpkg.json does it on the first build) and build with C++17 in Visual Studio
Put the app secret in at build time and never commit a real secret to a public repository
Step 3: sign in and start the heartbeat
#include "PwfClient.h"
PwfClient client(appSecret);
client.SetSessionEndedCallback([](const std::string& code, const std::string& message) {
// banned, paused, expired, reset, ended from the panel, or no server for 90 seconds
PostQuitMessage(0);
});
PwfResponse login = client.Login(licenseKey);
if (!login.Success()) {
ShowError(login.Message()); // written for the customer
return;
}
client.StartHeartbeat(); // the kill switch: never skip itStartHeartbeat() checks in with the server every 30 seconds. Ban, pause or expire the key in your panel and the callback runs on the next check-in. Three check-ins in a row without an encrypted answer end the session with NETWORK_LOST, so blocking the server in a firewall doesn't keep a banned copy running
Step 4: move a licence to a new PC
A key is bound to the first PC that signs in with it. When it is used on another PC, the sign-in answers HWID_MISMATCH (or DEVICE_LIMIT for a key allowed on several PCs). Offer to move it:
if (login.ErrorCode() == "HWID_MISMATCH" || login.ErrorCode() == "DEVICE_LIMIT") {
PwfResponse moved = client.ResetHardwareId(licenseKey, "Moved to a new PC");
if (moved.Success())
login = client.Login(licenseKey);
else
ShowError(moved.Message()); // for example the waiting time between two moves
}You decide in the panel whether customers may move keys themselves, and how long they wait between two moves
Customer accounts
Turn customer accounts on for the app and your customers can sign in with a username and a password instead of a key:
PwfResponse made = client.RegisterAccount("alice", "a-strong-password", "alice@example.com");
PwfResponse login = client.AccountLogin("alice", "a-strong-password");
if (login.Success()) client.StartHeartbeat();
// later: a key bought from a reseller adds its time to the account
PwfResponse added = client.RedeemKey("XXXXX-XXXXX-XXXXX-XXXXX");Built to resist a fake server
Every request carries a fresh random value, and every reply must carry the server's RSA signature over that exact request and reply. Knowing your app secret is not enough to fake an answer, and an unsigned or altered reply is refused before it is even read. A wrong PC clock repairs itself: when the server refuses the time, the client takes the server's clock and tries once more
The hardware ID is the same one the .NET, Python and Node.js packages use, so one PC counts as one device whatever language your apps use


