I’m once again back with a new version of the ISVLicenseGenerator tool, the piece of software I created with a modified version of the standard AXUtil.dll library that lets us sign license files using a cryptographic USB token.

ISVLicenseGenerator is not needed anymore and won’t be maintained.

As of version 10.0.43, and since 10.0.38, it’s possible to generate a license file using AXUtil using a HSM-backed certificate: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-tools/isv-licensing#create-a-package-and-generate-a-customer-specific-license

In the new version (v0.7) I’ve added the possibility of signing the license file using a certificate stored on an Azure Key Vault.

And this time I come with a request from anyone reading this post. If you have an HSM-protected key for your code-signing certificate, and are storing it in a Key Vault, I’d love you to try this new version out!

Why am I asking this? Well, I swear there are no hidden intentions here! The main reason is that I don’t have access to HSM keys, and I can’t test the new functionality with one of those. So if your certificate provider has a cloud HSM, and provides some sort of Azure Key Vault integration to store the keys in it, and you want to try it… I’ll be very happy to try to fix things if they don’t work!

What’s going on with ISV licensing?

In February 2024 AXUtil will stop allowing to use SHA1 as the signing algorithm. Something I did on ISVLicenseGenerator v0.6.

There’s something that, as far as I know, Microsoft still hasn’t solved, which is offering a solution for certificates that are delivered in a cryptographic USB token. Yes, my tool covers that, but I’d totally understand if some companies wouldn’t trust a community-made tool instead of an official Microsoft tool 🤷‍♂️

What’s new in version 0.7?

If you open the tool and see the UI, you’ll see it keeps the beautiful appearance, but with a few new fields on top:

ISVLicenseGenerator v0.7
ISVLicenseGenerator v0.7

Now you can select between signing the license file using the USB token or local certificate (that’s the existing functionality), or use a certificate stored on Azure Key Vault!

If you choose it as the certificate location, you’ll have to provide details in five more fields:

Azure Key Vault certificate additional fields
Azure Key Vault certificate additional fields
  • Key Vault DNS: this can be found in the overview tab of your Key Vault instance.
  • Key name: is the name of the certificate in Azure Key Vault where you’ve stored the code-signing certificate.
  • Entra ID Tenant Id: can be found on the main page of Entra ID in the Azure portal.
  • AppId: we’ll need an app registration to access the Key Vault from the application as a service principal.
  • Secret: the secret in the app registration.

Configuring Azure Key Vault

Let’s quickly see how to configure the Key Vault, store the certificate and add the app registration as a service principal.

First deploy an Azure Key Vault, it can be from the standard tier.

Azure Key Vault
Azure Key Vault

In the key vault you’ll see the DNS, which is the Vault URI field (and which I’ll have deleted once I’m done writing this post), and you also have the tenant Id in the Directory ID field below the DNS.

Now upload the certificate under the “Certificates” menu on the sidebar:

Import private key
Import private key

Remember here you need to upload your private key! The public key is used as a resource in Visual Studio when you create the configuration key used to lock your ISV.

The next step will be creating an App registration on Entra ID:

App registration
App registration

Here you will get the App Id in the Application (client) ID, and can get the tenant ID again.

Create a secret in the app registration and keep it somewhere safe.

Now we need to give this app registration rights on the Key Vault to access the certificate we’ll upload, and to sign the license. Go to the Key Vault and under Access management (IAM) on the sidebar we’ll add two roles.

Why two? We could accomplish this with a single role, but I want to reduce the amount of access rights for this app registration! First click the Add button on top and select “Add role assignment”. The first role we’ll add is the “Key Vault Certificate User” role:

Azure Key Vault support in ISVLicenseGenerator v0.7
Key Vault Certificate User

Click the next button, and click the “+ Select members” link, and look for the name of your app registration:

Add app registration
Add app registration

Click, select, then “Review + assign” twice.

Now repeat the steps for the “Key Vault Crypto User” role:

Key Vault Crypto User
Key Vault Crypto User

Once done we can go to ISVLicenseGenerator, fill in all the fields and click generate:

ISVLicenseGenerator v0.7
ISVLicenseGenerator v0.7

If all the information is correct you’ll get this nice success screen:

Success
Success

And you’ll have a working license to unlock your ISV!

What happens with the HSM-protected keys?

Well, that’s the question I’d also like to know the answer to! Unfortunately, I don’t have access to any certificate provider, and can’t check their HSM capabilities or if they have an integration for code-signing certificates to be stored in Azure Key Vault.

If this were possible, we could use the HSM capabilities of the Premium tier of Azure Key Vault, where we can create a Key Encryption Key (KEK) that’s later used to request a certificate from a certificate provider:

KEK generation
KEK generation

If you want to give it a try you can fork the repo on GitHub, and if you need any assistance from me, feel free to contact me. I’d love to add this feature to the tool.

Subscribe!

Receive an email when a new post is published
Author

Microsoft Dynamics 365 Finance & Operations technical architect and developer. Business Applications MVP since 2020.

7 Comments

  1. Hi Adria,

    Thanks for your nice blog and the latest tool to generate the license.

    I had followed the steps and able to generate the license successfully. One error I faced “The user, group or application does not have secrets get permission on key vault” after adding the app Id to the key vault access policy with key permission all able to generate the license key. However, when importing this license to one of our environments I am facing error message.

    “The certificate associated with license is not a trusted certificate.” on category error.
    Warning: method: readISVLicense, message: License value for *ISVLicenseCode* is incorrect. Not pretty sure the reason behind this error. If you have any idea on this could you share your insight ?

    Thanks
    Guru

    • My only guess would be that the user running the app needs to be using an account that exists in the Entra ID directory, and that they can be added to the security roles in Azure.

      • Thanks Adria for your input. I could able to generate the license key from your tool based on the Azure key vault approach. That is nice tool. But however when importing the license key to one of our internal environment (Deployed through deployable package) we face error message “The certificate associated with license is not a trusted certificate.” on category error. Warning: method: readISVLicense, message: License value for *ISVLicenseCode* is incorrect. We got the same error message when we generated the key from axUtil. This looks like irrespective of what type we follow same error persist. We have no clue what’s going wrong here.

  2. Vasyly Litovchenko Reply

    Hi Guru
    Recently we faced similar problem.
    First make sure your certificate indeed is trusted.
    If so make sure you have cer file with DER encoded binary content inside.
    We downloaded cer file from azure portal and it is in Base-64 encoded format.
    Windows handled that file just fine but AX kernel treated that certificate as not trusted.
    If it si your case – jest imported that certificate in local storage and exported that again in DER encoded binary X.509 (.CER)

    Hope that will help

    @Adria – thanks for the tool!!!

    • Vasyly, Thanks for your input indeed it worked out for us after reissuing certificate and imported that certificate in local storage and exported that again in DER encoded binary X.509 (.CER)

Write A Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.