Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save evanzhang89/22a5f73aaf238e0a712a6d753e1a4e0e to your computer and use it in GitHub Desktop.
Save evanzhang89/22a5f73aaf238e0a712a6d753e1a4e0e to your computer and use it in GitHub Desktop.
This is the script to generate the BEK file for unlocking the encrypted disk
Param(
[Parameter(Mandatory = $true,
HelpMessage="URL of the secret stored in the keyvault")]
[ValidateNotNullOrEmpty()]
[string]$secretUrl,
[Parameter(Mandatory = $true,
HelpMessage="Resource group of keyvault")]
[ValidateNotNullOrEmpty()]
[string]$keyVaultResourceGroup,
[Parameter(Mandatory = $true,
HelpMessage="URL of the KEK")]
[ValidateNotNullOrEmpty()]
[string]$kekUrl,
[Parameter(Mandatory = $true,
HelpMessage="Location where the retrieved secret should be written to")]
[ValidateNotNullOrEmpty()]
[string]$secretFilePath
)
Login-AzAccount;
#Install Active directory module
Install-Module -Name MSOnline;
#Get current logged in user and active directory tenant details
$ctx = Get-AzContext;
$adTenant = $ctx.Tenant.Id;
$currentUser = $ctx.Account.Id
#Parse the secret URL
$secretUri = [System.Uri] $secretUrl;
#Retrieve keyvault name, secret name and secret version from secret URL
$keyVaultName = $secretUri.Host.Split('.')[0];
$secretName = $secretUri.Segments[2].TrimEnd('/');
$secretVersion = $secretUri.Segments[3].TrimEnd('/');
#Set permissions for the current user to unwrap keys and retrieve secrets from KeyVault
$KeyVault = Get-AzKeyVault -VaultName $keyVaultName -ResourceGroupName $keyVaultResourceGroup;
$acl = $KeyVault.AccessPolicies;
$currentacl = $acl | Where-Object { $_.DisplayName -match $currentUser };
$aclp2k = $currentacl.PermissionsToKeys + "unwrapKey"
$aclp2s = $currentacl.PermissionsToSecrets + "get"
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -PermissionsToKeys $aclp2k -PermissionsToSecrets $aclp2s -UserPrincipalName $currentUser;
#Retrieve secret from KeyVault secretUrl
$keyVaultSecret = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $secretName -Version $secretVersion;
$secretBase64 = $keyVaultSecret.SecretValue;
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secretBase64)
$secretBase64 = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
#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.
########################################################################################################################
# Install the ADAL Module
Install-Module -Name Az.Accounts -Scope AllUsers -Repository PSGallery -Force -AllowClobber
$Token = "Bearer {0}" -f (Get-AzAccessToken -Resource "https://vault.azure.net").Token
$headers = @{
'Authorization' = $token
"x-ms-version" = '2014-08-01'
}
# Place wrapped BEK in JSON object to send to KeyVault REST API
########################################################################################################################
# 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
$secretBase64 = $result.value;
}
$secretBase64 = $secretBase64.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);
}
#Delete the key from the memory
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
clear-variable -name secretBase64
@evanzhang89
Copy link
Author

Get rid of ADAL library (which incurred extra complexity and made lot of errors) and use the new method to get the token (Get-AzAccessToken)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment