PowerShell/Docs/decrypt-file.md
2022-11-17 20:02:26 +01:00

6.4 KiB
Raw Blame History

The decrypt-file.ps1 PowerShell Script

This PowerShell script decrypts a file using the given password and AES encryption.

Parameters

decrypt-file.ps1 [[-Path] <String>] [[-Password] <String>] [<CommonParameters>]

-Path <String>
    Specifies the path to the file to decrypt
    
    Required?                    false
    Position?                    1
    Default value                
    Accept pipeline input?       false
    Accept wildcard characters?  false

-Password <String>
    Specifies the password
    
    Required?                    false
    Position?                    2
    Default value                
    Accept pipeline input?       false
    Accept wildcard characters?  false

[<CommonParameters>]
    This script supports the common parameters: Verbose, Debug, ErrorAction, ErrorVariable, WarningAction, 
    WarningVariable, OutBuffer, PipelineVariable, and OutVariable.

Example

PS> ./decrypt-file-rules C:\MyFile.txt "123"

Notes

Author: Markus Fleschutz | License: CC0

https://github.com/fleschutz/PowerShell

Source Code

<# .SYNOPSIS Decrypts a file .DESCRIPTION This PowerShell script decrypts a file using the given password and AES encryption. .PARAMETER Path Specifies the path to the file to decrypt .PARAMETER Password Specifies the password .EXAMPLE PS> ./decrypt-file-rules C:\MyFile.txt "123" .LINK https://github.com/fleschutz/PowerShell .NOTES Author: Markus Fleschutz | License: CC0 #>

param([string]$Path = "", [string]$Password = "")

function DecryptFile { [CmdletBinding(DefaultParameterSetName='SecureString')] [OutputType([System.IO.FileInfo[]])] Param( [Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [Alias('PSPath','LiteralPath')] [string[]]$FileName, [Parameter(Mandatory=$false, Position=2, ValueFromPipelineByPropertyName=$true)] [ValidateSet('AES','DES','RC2','Rijndael','TripleDES')] [String]$Algorithm = 'AES', [Parameter(Mandatory=$true, Position=3, ValueFromPipelineByPropertyName=$true, ParameterSetName='SecureString')] [System.Security.SecureString]$Key, [Parameter(Mandatory=$true, Position=3, ParameterSetName='PlainText')] [String]$KeyAsPlainText, [Parameter(Mandatory=$false, Position=4, ValueFromPipelineByPropertyName=$true)] [System.Security.Cryptography.CipherMode]$CipherMode = 'CBC', [Parameter(Mandatory=$false, Position=5, ValueFromPipelineByPropertyName=$true)] [System.Security.Cryptography.PaddingMode]$PaddingMode = 'PKCS7', [Parameter(Mandatory=$false, Position=6)] [String]$Suffix, [Parameter()] [Switch]$RemoveSource ) Process { try { if($PSCmdlet.ParameterSetName -eq 'PlainText') { $Key = $KeyAsPlainText | ConvertTo-SecureString -AsPlainText -Force }

        $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Key)
        $EncryptionKey = [System.Convert]::FromBase64String([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR))

        $Crypto = [System.Security.Cryptography.SymmetricAlgorithm]::Create($Algorithm)
        $Crypto.Mode = $CipherMode
        $Crypto.Padding = $PaddingMode
        $Crypto.KeySize = $EncryptionKey.Length*8
        $Crypto.Key = $EncryptionKey
    }
    Catch
    {
        Write-Error $_ -ErrorAction Stop
    }

    if(-not $PSBoundParameters.ContainsKey('Suffix'))
    {
        $Suffix = ".$Algorithm"
    }

    $Files = Get-Item -LiteralPath $FileName

    ForEach($File in $Files)
    {
        If(-not $File.Name.EndsWith($Suffix))
        {
            Write-Error "$($File.FullName) does not have an extension of '$Suffix'."
            Continue
        }

        $DestinationFile = $File.FullName -replace "$Suffix$"

        Try
        {
            $FileStreamReader = New-Object System.IO.FileStream($File.FullName, [System.IO.FileMode]::Open)
            $FileStreamWriter = New-Object System.IO.FileStream($DestinationFile, [System.IO.FileMode]::Create)

            [Byte[]]$LenIV = New-Object Byte[] 4
            $FileStreamReader.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null
            $FileStreamReader.Read($LenIV,  0, 3) | Out-Null
            [Int]$LIV = [System.BitConverter]::ToInt32($LenIV,  0)
            [Byte[]]$IV = New-Object Byte[] $LIV
            $FileStreamReader.Seek(4, [System.IO.SeekOrigin]::Begin) | Out-Null
            $FileStreamReader.Read($IV, 0, $LIV) | Out-Null
            $Crypto.IV = $IV

            $Transform = $Crypto.CreateDecryptor()
            $CryptoStream = New-Object System.Security.Cryptography.CryptoStream($FileStreamWriter, $Transform, [System.Security.Cryptography.CryptoStreamMode]::Write)
            $FileStreamReader.CopyTo($CryptoStream)

            $CryptoStream.FlushFinalBlock()
            $CryptoStream.Close()
            $FileStreamReader.Close()
            $FileStreamWriter.Close()

            if($RemoveSource){Remove-Item $File.FullName}

            Get-Item $DestinationFile | Add-Member MemberType NoteProperty Name SourceFile Value $File.FullName -PassThru
        }
        Catch
        {
            Write-Error $_
            If($FileStreamWriter)
            {
                $FileStreamWriter.Close()
                Remove-Item -LiteralPath $DestinationFile -Force
            }
            Continue
        }
        Finally
        {
            if($CryptoStream){$CryptoStream.Close()}
            if($FileStreamReader){$FileStreamReader.Close()}
            if($FileStreamWriter){$FileStreamWriter.Close()}
        }
    }
}

}

try { if ($Path -eq "" ) { $Path = read-host "Enter path to file" } if ($Password -eq "" ) { $Password = read-host "Enter password" } $StopWatch = [system.diagnostics.stopwatch]::startNew()

$PasswordBase64 = [System.Convert]::ToBase64String($Password)
DecryptFile "$Path" -Algorithm AES -KeyAsPlainText $PasswordBase64 -RemoveSource

[int]$Elapsed = $StopWatch.Elapsed.TotalSeconds
"✔️  file decrypted in $Elapsed sec"
exit 0 # success

} catch { "⚠️ Error in line $($_.InvocationInfo.ScriptLineNumber): $($Error[0])" exit 1 }

Generated by convert-ps2md.ps1 using the comment-based help of decrypt-file.ps1