Forked from vermashi/RetreiveEncryptionSecretViaUrl.ps1
Last active
May 4, 2021 21:35
-
-
Save killejay/49bf07e94baecc1e409d620822ae79cc to your computer and use it in GitHub Desktop.
Retrieve Encryption key via secret URL
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
# Sample Script Run command (could run without escalation): | |
# ./RetreiveEncryptionSecretViaUrl.ps1 -secretUrl xxx -kekUrl yyy -secretFilePath Output-KEK-key -vaultrg Resource-group-of-keyvault | |
Param( | |
[Parameter(Mandatory = $true, | |
HelpMessage="keyvault resource group name")] | |
[ValidateNotNullOrEmpty()] | |
[string]$vaultrg, | |
[Parameter(Mandatory = $true, | |
HelpMessage="URL to the secret stored in the keyvault")] | |
[ValidateNotNullOrEmpty()] | |
[string]$secretUrl, | |
[Parameter(Mandatory = $false, | |
HelpMessage="URL to the KEK")] | |
[ValidateNotNullOrEmpty()] | |
[string]$kekUrl, | |
[Parameter(Mandatory = $true, | |
HelpMessage="Location where the retrieved secret should be written to")] | |
[ValidateNotNullOrEmpty()] | |
[string]$secretFilePath | |
) | |
# if ((Test-Path -Path 'activedirectory-lib' -PathType Container)) | |
# { | |
# Write-Output "Previous temp lib folder detected, proceed to delete." | |
# Remove-Item -Path 'activedirectory-lib' -Force -Recurse | |
# } | |
#Login-AzureRmAccount; | |
#Install Active directory module | |
#Install-Module -Name MSOnline; | |
#Tested no need to load MSOnline lib. | |
#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 $vaultrg; | |
$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 -AsPlainText; | |
$secretBase64 = $keyVaultSecret; | |
#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. | |
######################################################################################################################## | |
# Get the Lib from external, using the traditional 2.29 version instead of the latest. | |
Invoke-WebRequest -Uri 'https://www.nuget.org/api/v2/package/Microsoft.IdentityModel.Clients.ActiveDirectory/2.29.0' -OutFile 'microsoft.identitymodel.clients.activedirectory.2.29.0.zip' | |
Expand-Archive -LiteralPath 'microsoft.identitymodel.clients.activedirectory.2.29.0.zip' -DestinationPath 'activedirectory-lib/' | |
Add-Type -Path 'activedirectory-lib/lib/net45/Microsoft.IdentityModel.Clients.ActiveDirectory.dll' | |
# 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=7.1"; | |
$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+= '='; | |
} | |
# Modified to prevent fallback use absulte address | |
if($secretFilePath) | |
{ | |
$bekFileBytes = [System.Convert]::FromBase64String($secretBase64); | |
$dec_secretBase64 = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secretBase64)); | |
Write-Output "Your original base64-wrapped secret is: "`r$secretBase64`n"" | |
if (![string]::IsNullOrEmpty($dec_secretBase64)){ | |
Write-Output "Your decrypyted BEK key is: "`r$($dec_secretBase64)"" | |
$confirmation = Read-Host "Generate the key file to current folder? (y/n)" | |
if ($confirmation -eq 'y') { | |
Out-File -FilePath $secretFilePath -InputObject $dec_secretBase64 | |
} | |
Remove-Item -Path 'microsoft.identitymodel.clients.activedirectory.2.29.0.zip' -Force | |
Write-Output "Script run finished."`r">>Remerber to close this PowerShell windows, and then delete the activedirectory-lib folder manually." | |
} | |
else { | |
Write-Output "!! Retrive Key failed, please check KeyVault access permission or other settings." | |
Remove-Item -Path 'activedirectory-lib' -Force -Recurse | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example:
C:\Scripts\RetreiveEncryptionSecretViaUrl.ps1 -vaultrg testrg -secretUrl https://.vault.azure.net/secrets//* -kekUrl https://.vault.azure.net:443/keys//*** -secretFilePath C:\BEK\TestKEK**