Encrypt a sensitive information with Azure Key Vault
Things Azure Key Vault protects
Key
Cryptographic keys used in other Microsoft Azure services
Secret
Any sensitive information such as connection strings to SQL Server, Redis, or Storage.
Certificate
x509 certificates being used in HTTPS / SSL communications
Provision key Vault with Terraform
resource "azurerm_resource_group" "web-resource-group" {
name = "${var.organisation}-${var.system}-${var.environment}-web-${var.location}"
location = var.location
tags = var.tags
}
resource "azurerm_key_vault" "web" {
name = "${var.environment}-web"
resource_group_name = azurerm_resource_group.web-resource-group.name
location = azurerm_resource_group.web-resource-group.location
sku_name = "standard"
tenant_id = data.azurerm_client_config.client_config.tenant_id
enabled_for_deployment = true
enabled_for_template_deployment = true
tags = var.tags
}
# Access to terraform SP
data "azurerm_client_config" "client_config" {}
resource "azurerm_key_vault_access_policy" "ci" {
key_vault_id = azurerm_key_vault.web.id
tenant_id = data.azurerm_client_config.client_config.tenant_id
object_id = data.azurerm_client_config.client_config.object_id
certificate_permissions = [
"get",
"list",
"update",
"create",
"import",
"delete",
"managecontacts",
"manageissuers",
"getissuers",
"listissuers",
"setissuers",
"deleteissuers",
"backup",
"purge",
"recover",
"restore",
]
key_permissions = [
"create",
"decrypt",
"delete",
"encrypt",
"get",
"import",
"list",
"purge",
"recover",
"restore",
"sign",
"unwrapKey",
"update",
"verify",
"wrapKey",
]
secret_permissions = [
"delete",
"get",
"list",
"set",
"backup",
"purge",
"recover",
"restore",
]
storage_permissions = [
"backup",
"delete",
"deletesas",
"get",
"getsas",
"list",
"listsas",
"purge",
"recover",
"regeneratekey",
"restore",
"set",
"setsas",
"update",
]
}
resource "azurerm_key_vault_access_policy" "web-service-principle" {
key_vault_id = azurerm_key_vault.web.id
tenant_id = data.azurerm_client_config.client_config.tenant_id
object_id = data.azurerm_client_config.client_config.object_id
certificate_permissions = [
"get"
]
key_permissions = [
"get"
]
secret_permissions = [
"get"
]
}
output "web_keyvault_url" {
value = azurerm_key_vault.web.vault_uri
}
Encrypt and decrypt your token
Use symmetric key if you need to encrypt the information and also to decrypt it. In this case, you need to store the encrypting key in Azure Key Vault secret. For asymmetric encryption, you can use Azure Key Vault key.
I’m using Aes from Cryptographic servieces .NET provides.
// sample code. In real situation, the Key and IV will come from Azure Key Vault secrets
public class EncryptionService
{
readonly byte[] _key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
// Actually, the iv should be new on every encryption. You can save it as salt in the database
readonly byte[] _iv = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
public string Encrypt(string token)
{
using (var aes = Aes.Create())
{
aes.Key = _key;
aes.IV = _iv;
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream,
aes.CreateEncryptor(aes.Key, aes.IV),
CryptoStreamMode.Write))
{
using (var streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(token);
}
return Convert.ToBase64String(memoryStream.ToArray());
}
}
}
}
public string Decrypt(string encryptedToken)
{
var buffer = Convert.FromBase64String(encryptedToken);
using (var aes = Aes.Create())
{
aes.Key = _key;
aes.IV = _iv;
using (var memoryStream = new MemoryStream(buffer))
{
using (var cryptoStream = new CryptoStream(memoryStream,
aes.CreateDecryptor(aes.Key, aes.IV),
CryptoStreamMode.Read))
{
using (var streamReader = new StreamReader(cryptoStream))
{
return streamReader.ReadToEnd();
}
}
}
}
}
}
Comments