My desktop app is used by customers. A customer is a user with a License Key AND his computer's MAC address. The desktop application can only be used on ONE instance.
So when a user buys a license and registers it (meaning he downloaded, opened the desktop app, entered and submitted his license key), I will first retrieve his MAC address and then do a POST
request to my API, /user
with parameters in that way {license-key: "license_here", mac-address: "mac_here"}
so these are saved into my database.
Now, how should I do to secure the API calls in the desktop app, once the user is registered?
Let's say a user wants to access his setting tab, should I provide {license-key: "license_here", mac-address: "mac_here"}
as parameters to the GET
request and check if it matches his License Key and MAC address in my database, and if it does, display all his settings retrieved from the database on the setting tab?
Or is there a more secure way to do that?
Another way I thought would be for example to hash
the license key and the MAC address, concat
them and use that an authentication token that I would use for each request.
I am using an API instead of saving locally because I will create a mobile app once I am done with the desktop app, and I will need to share information between both apps.
Using NodeJS
with Express
and MongoDB/Mongoose
.
What you are doing is attempting to authenticate the computer using some data/knowledge that only it has (its MAC and licence key). This is easy to get around as an unlicensed computer can spoof the data and fool you into thinking the request is coming from an licensed computer. If you only transmit the license/MAC data then its possible for any other computer with the knowledge to also impersonate a licensed computer just by intercepting a single request - all the info required to impersonate is contained within the request.
You can't enforce uniqueness of a computer without specialised hardware. This usually takes the form of a dedicated microchip that contains a key or certificate. The data cannot be read from the chip, but the chip can be used to create a digital signature.
Without dedicated hardware the best you can do is to use a unique license key per computer and require all requests to be signed using this key. This relies on the key being private (the signature is sent with the message, not the key itself) and is no guarantee as you don't control the client computer.
Edit - How this works:
Issue a license key to each client. On your server, record each key you issue against the MAC address of the computer it is assigned to. You should probably collect the MAC address at the time of issuing the licence. Do not get clients to 'register' their license. Clients must use the key to sign each request they send and include the signature and MAC in each request. At the server you validate each incoming request by looking up the key using the MAC address and recreating the signature yourself. If the signature matches the one supplied by the client then you know its genuine. Remember - this is still not foolproof! I can buy one license from you and install it on any number of computers so long as I get them all to fake the approved MAC address. I can also give my key to my friends and have them fake the MAC address too.