Created
April 20, 2018 01:06
-
-
Save vermashi/3745c8503a2166f0a5eb9d72c2e2a2fc to your computer and use it in GitHub Desktop.
Retrieve the encryption secret (aka passphrase) from Azure Key Vault
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Param( | |
[Parameter(Mandatory = $true, | |
HelpMessage="ResourceGroup name of the vm")] | |
[ValidateNotNullOrEmpty()] | |
[string]$rgName, | |
[Parameter(Mandatory = $true, | |
HelpMessage="VM name")] | |
[ValidateNotNullOrEmpty()] | |
[string]$vmName, | |
[Parameter(Mandatory = $true, | |
HelpMessage="Location where the retrieved secret should be written to")] | |
[ValidateNotNullOrEmpty()] | |
[string]$secretFilePath | |
) | |
#Login-AzureRmAccount; | |
#Install Active directory module | |
Install-Module -Name MSOnline; | |
#Get current logged in user and active directory tenant details | |
$ctx = Get-AzureRmContext; | |
$adTenant = $ctx.Tenant.Id; | |
$currentUser = $ctx.Account.Id | |
#Get encryption secret url and kek url from VM's encryption settings | |
$vm = Get-AzureRmVm -ResourceGroupName $rgName -Name $vmName; | |
$secretUrl = $vm.StorageProfile.OsDisk.EncryptionSettings.DiskEncryptionKey.SecretUrl; | |
$secretUrl = [System.Uri]$secretUrl; | |
#if encrypted using KEK | |
if($vm.StorageProfile.OsDisk.EncryptionSettings.KeyEncryptionKey) | |
{ | |
$kekUrl = $vm.StorageProfile.OsDisk.EncryptionSettings.KeyEncryptionKey.KeyUrl | |
} | |
#Retrieve keyvault name, secret name and secret version from secret URL | |
$keyVaultName = $secretUrl.Host.Split('.')[0]; | |
$secretName = $secretUrl.Segments[2].TrimEnd('/'); | |
$secretVersion = $secretUrl.Segments[3].TrimEnd('/'); | |
#Set permissions for the current user to unwrap keys and retrieve secrets from KeyVault | |
Set-AzureRmKeyVaultAccessPolicy -VaultName $keyVaultName -PermissionsToKeys all -PermissionsToSecrets all -UserPrincipalName $currentUser; | |
#Retrieve secret from KeyVault secretUrl | |
$keyVaultSecret = Get-AzureKeyVaultSecret -VaultName $keyVaultName -Name $secretName -Version $secretVersion; | |
$secretBase64 = $keyVaultSecret.SecretValueText; | |
#Unwrap secret if the secret is wrapped with KEK | |
if($kekUrl) | |
{ | |
######################################################################################################################## | |
# Initialize ADAL libraries and get authentication context required to make REST API called against KeyVault REST APIs. | |
######################################################################################################################## | |
# Set well-known client ID for AzurePowerShell | |
$clientId = "1950a258-227b-4e31-a9cf-717495945fc2" | |
# Set redirect URI for Azure PowerShell | |
$redirectUri = "urn:ietf:wg:oauth:2.0:oob" | |
# Set Resource URI to Azure Service Management API | |
$resourceAppIdURI = "https://vault.azure.net" | |
# Set Authority to Azure AD Tenant | |
$authority = "https://login.windows.net/$adTenant" | |
# Create Authentication Context tied to Azure AD Tenant | |
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority | |
# Acquire token | |
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto") | |
# Generate auth header | |
$authHeader = $authResult.CreateAuthorizationHeader() | |
# Set HTTP request headers to include Authorization header | |
$headers = @{'x-ms-version'='2014-08-01';"Authorization" = $authHeader} | |
######################################################################################################################## | |
# 1. Retrieve the secret from KeyVault | |
# 2. If Kek is not NULL, unwrap the secret with Kek by making KeyVault REST API call | |
# 3. Convert Base64 string to bytes and write to the BEK file | |
######################################################################################################################## | |
#Call KeyVault REST API to Unwrap | |
$jsonObject = @" | |
{ | |
"alg": "RSA-OAEP", | |
"value" : "$secretBase64" | |
} | |
"@ | |
$unwrapKeyRequestUrl = $kekUrl+ "/unwrapkey?api-version=2015-06-01"; | |
$result = Invoke-RestMethod -Method POST -Uri $unwrapKeyRequestUrl -Headers $headers -Body $jsonObject -ContentType "application/json"; | |
#Convert Base64Url string returned by KeyVault unwrap to Base64 string | |
$secretBase64Url = $result.value; | |
$secretBase64 = $secretBase64Url.Replace('-', '+'); | |
$secretBase64 = $secretBase64.Replace('_', '/'); | |
if($secretBase64.Length %4 -eq 2) | |
{ | |
$secretBase64+= '=='; | |
} | |
elseif($secretBase64.Length %4 -eq 3) | |
{ | |
$secretBase64+= '='; | |
} | |
} | |
if($secretFilePath) | |
{ | |
$bekFileBytes = [System.Convert]::FromBase64String($secretBase64); | |
[System.IO.File]::WriteAllBytes($secretFilePath,$bekFileBytes); | |
} |
ADE itself is terrible!
Hi
when trying to run the script I get
ou cannot call a method on a null-valued expression.
At line:40 char:1
- $keyVaultName = $secretUrl.Host.Split('.')[0];
-
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull
I guess its becuase the encryption settings is empty but from checking the VM the disk is encrypted.
happy if you can assist.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you -- you saved me a lot of misery figuring this out. The ADE docs are terrible!