Private/Protect-HDTShareSecret.ps1
|
function Protect-HDTShareSecret { <# .SYNOPSIS Obfuscates the share password for storage in Control\share-credential.json. .DESCRIPTION AES-CBC with a random IV and the module constant from Get-HDTShareSecretKey, base64 encoded as IV followed by ciphertext. IT IS OBFUSCATION AND IT IS NOT CLAIMED AS SECURITY. The key is in the module, the module is in the boot image, and the boot image is handed to whichever machine PXE boots - so anyone who can read either can recover the password. HDT says exactly that: the file this writes carries a warning sentence saying it, and docs/share-account.md says it again in prose. What this buys is that the password is not sitting in plain text in a JSON file on a share, which is a real if modest thing. NOT DPAPI, deliberately: DPAPI is user- and machine-bound and the value has to be readable inside WinPE on a machine that has never seen the one that wrote it. .PARAMETER Secret The plain text to obfuscate. .OUTPUTS System.String - base64 of the IV followed by the ciphertext. .EXAMPLE Protect-HDTShareSecret -Secret $plain #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '', Justification = 'This is the function that turns the plain text into the stored form; taking a SecureString here would unwrap it one line later.')] [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory = $true, Position = 0)] [AllowEmptyString()] [string] $Secret ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $aes = [System.Security.Cryptography.Aes]::Create() try { $aes.Key = Get-HDTShareSecretKey $aes.GenerateIV() $encryptor = $aes.CreateEncryptor() try { $plain = [System.Text.Encoding]::UTF8.GetBytes($Secret) $cipher = $encryptor.TransformFinalBlock($plain, 0, $plain.Length) return [System.Convert]::ToBase64String($aes.IV + $cipher) } finally { $encryptor.Dispose() } } finally { $aes.Dispose() } } |