Using flutter_secure_storage for license key activation data

Say, I have a desktop app that can be purchased as a 1 time payment and the user gets their unique license key.

Also, assume that the app does come with a private backend to handle license key activation and recording registered device ids etc.

It is my understanding that for the most part flutter_secure_storage should generally be good enough on most platforms to store activation details securely on device. On MacOS it uses the user’s keychain, so there is no easy way to hijack or transfer this data to another device.

I’m struggling to understand the Windows implementation of the package. It appears that general advice is to use CryptProtectData DPAPI to encypt such information, as this API is bound to the user’s login on the device, hence it’s secure, and can’t be easily transferred between devices.

But looking at the native side of the plugin it’s not using the DPAPI, if I’m not mistaken, and instead deals with generating its own encryption key, etc.

Anyone with experience here of trying to implement something similar? Did you use flutter_secure_storage or something else?

1 Like

Client side encryption is as useful as attaching the key to a lock and sticking a note saying “Please, don’t open”

If I would implement such thing, I would ask my backend to create a JWT with the license data, issued to the user id (it can be its ID or the e-mail, although in the latter you would not be able to let the user update it), with an expiration date (or not).

The JWT signature can be then checked on the client without the need to disclosure any private keys.

The security in this case would be the authenticated user. If the user is what he/she claims to be, and the signature matches, the license is ok.

But, if the license is only for a single computer, then, you’ll need to implement usage (it is possible to get, for instance, the MacOS serial number and bind the license to that specific machine. If the user buy a new computer, it would then deactivate the license on that machine and reactivate on another). Windows and Linux would be easy as well, you could get the mother board ID, for instance.

Now, nothing of that matters on mobile, since you can’t do payment outside the app stores (and, for all that stuff, RevenueCat would cover everything).

I think you misunderstood the original question. He already states that the licence is managed by the backend but asks where to securely store the once obtained licence/login token which you typically put into secure_storage.

What @escamoteur said is correct.

But also, my question is more specific to the flutter_secure_storage itself, and its Windows implementation.

JWT or not, I’d want to persist that locally on the device so that when user restarts the app I can securely retrieve this information, validate and move on.

1 Like

This is the precise location in the Windows code for flutter_secure_storage: flutter_secure_storage/flutter_secure_storage_windows/windows/flutter_secure_storage_windows_plugin.cpp at 5edd3b145023311d28be68757fc1360ad8f54d96 · juliansteenbakker/flutter_secure_storage · GitHub. It will save on roaming folder using CredReadW (flutter_secure_storage/flutter_secure_storage_windows/windows/flutter_secure_storage_windows_plugin.cpp at 5edd3b145023311d28be68757fc1360ad8f54d96 · juliansteenbakker/flutter_secure_storage · GitHub).

CredReadW is the api for Windows Credentials Manager, but no local credential (not even KeyChain) is secure: CredentialsFileView - Decrypt the Credentials files of Windows, hence, my comment about SIGNING the license instead of trying to hide it through encryption.

Almost the same as MacOS and its KeyChain.

4 Likes

Please check security - How do I store and retrieve credentials from the Windows Vault credential manager? - Stack Overflow
It seems that CredReadW is indeed secure for Win10/11 professional

2 Likes

Thank you guys, this is exactly what I was looking for!

For some reason my googling only showed me CryptProtectData posts.

So it appears that the plugin generates encryption key and stores that using CredReadW and then uses that to encrypt actual application data.

2 Likes