Private/Storage/ActiveDirectory/Protect-PukAdAttributeValue.ps1
|
function Protect-PukAdAttributeValue { [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory)] [psobject]$InputObject, [Parameter(Mandatory)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate ) # AesGcm (authenticated encryption in one step) requires .NET Core 3.0+ and does not exist # on .NET Framework, so it can't be used here without breaking Windows PowerShell 5.1 # compatibility. Instead: AES-256-CBC plus an independent Encrypt-then-MAC HMAC-SHA256 tag # (computed over IV || ciphertext) gives equivalent tamper-detection on both engines. $aesMaterial = New-PukAesKey $combinedKeyMaterial = $aesMaterial.Key + $aesMaterial.HmacKey $wrappedKey = Protect-PukAesKeyWithCertificate -Key $combinedKeyMaterial -Certificate $Certificate $plaintextBytes = [System.Text.Encoding]::UTF8.GetBytes(($InputObject | ConvertTo-Json -Depth 10)) $aes = [System.Security.Cryptography.Aes]::Create() try { $aes.Key = $aesMaterial.Key $aes.IV = $aesMaterial.IV $encryptor = $aes.CreateEncryptor() try { $cipherBytes = $encryptor.TransformFinalBlock($plaintextBytes, 0, $plaintextBytes.Length) } finally { $encryptor.Dispose() } } finally { $aes.Dispose() } $hmac = [System.Security.Cryptography.HMACSHA256]::new($aesMaterial.HmacKey) try { $macBytes = $hmac.ComputeHash($aesMaterial.IV + $cipherBytes) } finally { $hmac.Dispose() } $wrappedKeyB64 = [Convert]::ToBase64String($wrappedKey) $ivB64 = [Convert]::ToBase64String($aesMaterial.IV) $cipherB64 = [Convert]::ToBase64String($cipherBytes) $macB64 = [Convert]::ToBase64String($macBytes) return "$wrappedKeyB64.$ivB64.$cipherB64.$macB64" } |