script/encryption/public/Get-DecryptedString.ps1
Function Get-DecryptedString { Param( [Parameter(Mandatory)][SecureString]$Passphrase, [Parameter(Mandatory, ValueFromPipeline)][string]$CipherText ) Process { $derivationIterations = 1000 # Get the complete stream of bytes that represent: # [32 bytes of Salt] + [16 bytes of IV] + [n bytes of CipherText] $cipherTextBytesWithSaltAndIv = [Convert]::FromBase64String($CipherText) # Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes. $saltStringBytes = $cipherTextBytesWithSaltAndIv | Select-Object -First 32 # Get the IV bytes by extracting the next 16 bytes from the supplied cipherText bytes. $ivStringBytes = $cipherTextBytesWithSaltAndIv | Select-Object -Skip 32 -First 16 # Get the actual cipher text bytes by removing the first 48 bytes # from the cipherText string. $cipherTextBytes = $cipherTextBytesWithSaltAndIv | Select-Object -Skip 48 try { $password = [System.Security.Cryptography.Rfc2898DeriveBytes]::new( ($Passphrase | ConvertFrom-SecureString -AsPlainText), $saltStringBytes, $derivationIterations) $keyBytes = $password.GetBytes(32); $symmetricKey = [System.Security.Cryptography.RijndaelManaged]::new() $symmetricKey.BlockSize = 128 $symmetricKey.Mode = [System.Security.Cryptography.CipherMode]::CBC $symmetricKey.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7 $decryptor = $symmetricKey.CreateDecryptor($keyBytes, $ivStringBytes) $memoryStream = [System.IO.MemoryStream]::new($cipherTextBytes) $cryptoStream = [System.Security.Cryptography.CryptoStream]::new( $memoryStream, $decryptor, "Read") $plainTextBytes = [byte[]]::new($cipherTextBytes.Length) $decryptedByteCount = $cryptoStream.Read($plainTextBytes, 0, $plainTextBytes.Length); $memoryStream.Close(); $cryptoStream.Close(); return [System.Text.Encoding]::Utf8.GetString($plainTextBytes, 0, $decryptedByteCount) } finally { $password ? $password.Dispose() : $null $symmetricKey ? $symmetricKey.Dispose() : $null $encryptor ? $encryptor.Dispose() : $null $memoryStream ? $memoryStream.Dispose() : $null $cryptoStream ? $cryptoStream.Dispose() : $null } } } |