Search code examples
.netpowershellencryptionpowershell-4.0encryption-symmetric

Is this a proper way to AES encrypt larger file in powershell?


I've tried first by loading the file content into some variable with [IO.File]::ReadAllBytes

But that takes a lot of RAM and it's painfully slow.

So here's what I've got:

ErrorActionPreference = "Stop"
$AES = [System.Security.Cryptography.AES]::Create()
$AES.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
$AES.Mode = [System.Security.Cryptography.CipherMode]::CBC
$AES.BlockSize = 128
$AES.KeySize = 256
$AES.GenerateKey()
$AES.GenerateIV()
$Encryptor = $AES.CreateEncryptor()

$File = Get-Item -Path "C:\Myfile.exe"

$InputStream = New-Object System.IO.FileStream($File, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
$OutputStream = New-Object System.IO.FileStream((($File.FullName) + ".AES"), [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)

$CryptoStream = New-Object System.Security.Cryptography.CryptoStream($OutputStream, $Encryptor, [System.Security.Cryptography.CryptoStreamMode]::Write)

$InputStream.CopyTo($CryptoStream)
$CryptoStream.Dispose()

$AES.Dispose()

It works. However I was wondering if this is how it's supposed to be done. Do I not need to prepend IV to the beginning of the file, or does it happen automatically with the Encryptor?

Thanks for any responses in advance.


Solution

  • Yes, use streams and CopyTo. Yes, you should probably prefix the IV, no it doesn't do this automatically.

    Note that you provide confidentiality, but no authenticity / integrity. This could be fine for encrypting files though.

    You have used Aes.Create() and indicated the exact mode of operation & padding, which is as it should be.


    Note that this is not a security review. The destruction of the original file or the use case for encrypting an executable is not considered.