Extension: IEncryptionKey - quandis/qbo3-Documentation GitHub Wiki

The IEncryptionKey interface support symmetric encryption, typically used to encrypt small strings like passwords. Quandis recommends storing keys in a key management service such as AWS Key Management Service or Azure KeyVault. In each case, the keys are not stored in QBO instances, but accessed as a service, reducing the likelihood of compromised keys.

The IEncryptionKey interface requires implementation of:

public interface IEncryptionKey
{
  Task<string> EncryptAsync(string textToEncrypt);
  Task<string> DecryptAsync(string textToDecrypt);
}

To use encryption keys configured with QBO:

var encryptionKeyConfiguration = EncryptionKeyConfiguration.Load();
key = encryptionKeyConfiguration.GetEncryptionKey(encryptionKeyConfiguration.DefaultEncryptionKey);
var secret = await key.EncryptAsync("secret"); // returns an encrypted version of the word 'secret'
var clear = await key.DecryptAsync(secret);  // returns 'secret'

Keys configured in QBO are configured with a name, such as 'MyUATKey', and may be retrieved by name:

key = encryptionKeyConfiguration.GetEncryptionKey("MyUATKey");

If your code simply needs a key, but you don't care which key is used, leverage the EncryptionKeyConfiguration.DefaultEncryptionKey, which will use a key specified by the application setting qbo.Application.Properties.Settings.Default.DefaultEncryptionKey if defined, otherwise will fetch the first key used.

Caution: the following steps can result in incorrect decryption:

  • configure a single key in QBO; let's call this myFirstKey
  • use code that leverages the DefaultEncryptionKey
  • configure a second key in QBO; let's call this aSecondKey

In this scenario, set the qbo.Application.Properties.Settings.Default.DefaultEncryptionKey = 'myFirstKey' so that string encrypted before aSecondKey was added continue to be decrypted with myFirstKey.

Azure Key Vault Configuration

An Azure Key Vault can be created and managed by using the Azure Portal front end through a browser, or through a command line interface using the Azure CLI tool set. More information is available here.

Regardless of which tool you want to use, the following must be done:

  1. Create the KeyVault
  2. Create a key in the KeyVault
  3. Register the subject application/vm with Azure AD
  4. Assign an access policy on the KeyVault for our application/vm (in other words, give it permissions).

After these steps have been completed, we can configure an EncryptionKey in our qbo environment to encrypt and decrypt credentials using our new KeyVault and Key.

Helpful command line instructions

The full reference of KeyVault commands is available here.

Register Key Vault to the subscription. Only needs to be ran once per subscription.

az provider register -n Microsoft.KeyVault

Create the KeyVault, will return - name: name of vault; vaultUri: base uri for new vault.

az keyvault create --name 'Name Of Vault' --resource-group 'Name of ResourceGroup to Use' --location 'East US'

Create a key in the vault. Leave protection as software. Can reference the key now with KeyVault uri base + /keys/KeyName such as https://NameOfVault.vault.azure.net/keys/NameOfKey or a specific version https://NameOfVault.vault.azure.net/keys/NameOfKey/cgacf4f763ar42ffb0a1gca546aygd87

az keyvault key create --vault-name 'Name Of Vault' --name 'Name Of Key' --protection software

List our keys if needed

az keyvault key list --vault-name 'Name of Vault'

For our VM/Application Create a service principal and configure its access to Azure resources. If you don't specify a password, one will be created for you. Need the 'appId' returned from this which identifies our application in Azure AD

az ad sp create-for-rbac -n "MyApp" --password 'Pa$$w0rd' --skip-assignment

Now that our application is registered, we can assign it permissions to use in the KeyVault

az keyvault set-policy --name 'NameOfVault' --spn 'Replace following with Azure AD appId related to previous command'8f8c4bbd-485b-45fd-98f7-ec6300b7b4ed --key-permissions 'IEncryption requires the following'get decrypt

Delete a vault

az keyvault delete --name 'NameOfVault'

Delete a key

az keyvault key delete --vault-name 'NameOfVault' --name 'NameOfKey'

⚠️ **GitHub.com Fallback** ⚠️