Forked from ShridharParameshwarBhat/GenerateBEKFileForDiskUnlock.ps1
Last active
September 17, 2021 08:48
-
-
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
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="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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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)