Added encrypt-file.ps1 and decrypt-file.ps1

This commit is contained in:
Markus Fleschutz 2021-01-04 09:09:52 +00:00
parent 5aa8199346
commit 7641b29e7c
5 changed files with 392 additions and 401 deletions

View File

@ -11,10 +11,12 @@ close-thunderbird.ps1, closes Mozilla Thunderbird gracefully
close-windows-terminal.ps1, closes Windows Terminal gracefully
configure-git.ps1, sets up the Git configuration
csv-to-text.ps1, converts the given CSV file into a text list
decrypt-file.ps1, decrypts the given file
display-time.ps1, displays the current time
download.ps1, downloads the file/directory from the given URL
empty-dir.ps1, empties the given directory
enable-crash-dumps.ps1, enables the writing of crash dumps
encrypt-file.ps1, encrypts the given file
generate-qrcode.ps1, generates a QR code
inspect-exe.ps1, prints basic information of the given executable file
list-anagrams.ps1, lists all anagrams of the given word

1 Filename Description
11 close-windows-terminal.ps1 closes Windows Terminal gracefully
12 configure-git.ps1 sets up the Git configuration
13 csv-to-text.ps1 converts the given CSV file into a text list
14 decrypt-file.ps1 decrypts the given file
15 display-time.ps1 displays the current time
16 download.ps1 downloads the file/directory from the given URL
17 empty-dir.ps1 empties the given directory
18 enable-crash-dumps.ps1 enables the writing of crash dumps
19 encrypt-file.ps1 encrypts the given file
20 generate-qrcode.ps1 generates a QR code
21 inspect-exe.ps1 prints basic information of the given executable file
22 list-anagrams.ps1 lists all anagrams of the given word

View File

@ -1,401 +0,0 @@
function New-CryptographyKey()
{
<#
.SYNOPSIS
Generates a random cryptography key.
.DESCRIPTION
Generates a random cryptography key based on the desired key size.
.PARAMETER Algorithm
Algorithm to generate key for.
.PARAMETER KeySize
Number of bits the generated key will have.
.PARAMETER AsPlainText
Returns a String instead of SecureString.
.OUTPUTS
System.Security.SecureString. New-CryptographyKey return the key as a SecureString by default.
System.String. New-CryptographyKey will return the key in plain text as a string if the -AsPlainText parameter is specified.
.EXAMPLE
$key = New-CryptographyKey
This example generates a random 256-bit AES key and stores it in the variable $key.
.NOTES
Author: Tyler Siegrist
Date: 9/22/2017
#>
[CmdletBinding()]
[OutputType([System.Security.SecureString])]
[OutputType([String], ParameterSetName='PlainText')]
Param(
[Parameter(Mandatory=$false, Position=1)]
[ValidateSet('AES','DES','RC2','Rijndael','TripleDES')]
[String]$Algorithm='AES',
[Parameter(Mandatory=$false, Position=2)]
[Int]$KeySize,
[Parameter(ParameterSetName='PlainText')]
[Switch]$AsPlainText
)
Process
{
try
{
$Crypto = [System.Security.Cryptography.SymmetricAlgorithm]::Create($Algorithm)
if($PSBoundParameters.ContainsKey('KeySize')){
$Crypto.KeySize = $KeySize
}
$Crypto.GenerateKey()
if($AsPlainText)
{
return [System.Convert]::ToBase64String($Crypto.Key)
}
else
{
return [System.Convert]::ToBase64String($Crypto.Key) | ConvertTo-SecureString -AsPlainText -Force
}
}
catch
{
Write-Error $_
}
}
}
Function Protect-File
{
<#
.SYNOPSIS
Encrypts a file using a symmetrical algorithm.
.DESCRIPTION
Encrypts a file using a symmetrical algorithm.
.PARAMETER FileName
File(s) to be encrypted.
.PARAMETER Key
Cryptography key as a SecureString to be used for encryption.
.PARAMETER KeyAsPlainText
Cryptography key as a String to be used for encryption.
.PARAMETER CipherMode
Specifies the block cipher mode to use for encryption.
.PARAMETER PaddingMode
Specifies the type of padding to apply when the message data block is shorter than the full number of bytes needed for a cryptographic operation.
.PARAMETER Suffix
Suffix of the encrypted file to be removed.
.PARAMETER RemoveSource
Removes the source (decrypted) file after encrypting.
.OUTPUTS
System.IO.FileInfo. Protect-File will return FileInfo with the SourceFile, Algorithm, Key, CipherMode, and PaddingMode as added NoteProperties
.EXAMPLE
Protect-File 'C:\secrets.txt' $key
This example encrypts C:\secrets.txt using the key stored in the variable $key. The encrypted file would have the default extension of '.AES' and the source (decrypted) file would not be removed.
.EXAMPLE
Protect-File 'C:\secrets.txt' -Algorithm DES -Suffix '.Encrypted' -RemoveSource
This example encrypts C:\secrets.txt with a randomly generated DES key. The encrypted file would have an extension of '.Encrypted' and the source (decrypted) file would be removed.
.EXAMPLE
Get-ChildItem 'C:\Files' -Recurse | Protect-File -Algorithm AES -Key $key -RemoveSource
This example encrypts all of the files under the C:\Files directory using the key stored in the variable $key. The encrypted files would have the default extension of '.AES' and the source (decrypted) files would be removed.
.NOTES
Author: Tyler Siegrist
Date: 9/22/2017
#>
[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)]
[ValidateSet('AES','DES','RC2','Rijndael','TripleDES')]
[String]$Algorithm = 'AES',
[Parameter(Mandatory=$false, Position=3, ParameterSetName='SecureString')]
[System.Security.SecureString]$Key = (New-CryptographyKey -Algorithm $Algorithm),
[Parameter(Mandatory=$true, Position=3, ParameterSetName='PlainText')]
[String]$KeyAsPlainText,
[Parameter(Mandatory=$false, Position=4)]
[System.Security.Cryptography.CipherMode]$CipherMode,
[Parameter(Mandatory=$false, Position=5)]
[System.Security.Cryptography.PaddingMode]$PaddingMode,
[Parameter(Mandatory=$false, Position=6)]
[String]$Suffix = ".$Algorithm",
[Parameter()]
[Switch]$RemoveSource
)
Begin
{
#Configure cryptography
try
{
if($PSCmdlet.ParameterSetName -eq 'PlainText')
{
$Key = $KeyAsPlainText | ConvertTo-SecureString -AsPlainText -Force
}
#Decrypt cryptography Key from SecureString
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Key)
$EncryptionKey = [System.Convert]::FromBase64String([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR))
$Crypto = [System.Security.Cryptography.SymmetricAlgorithm]::Create($Algorithm)
if($PSBoundParameters.ContainsKey('CipherMode')){
$Crypto.Mode = $CipherMode
}
if($PSBoundParameters.ContainsKey('PaddingMode')){
$Crypto.Padding = $PaddingMode
}
$Crypto.KeySize = $EncryptionKey.Length*8
$Crypto.Key = $EncryptionKey
}
Catch
{
Write-Error $_ -ErrorAction Stop
}
}
Process
{
$Files = Get-Item -LiteralPath $FileName
ForEach($File in $Files)
{
$DestinationFile = $File.FullName + $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)
#Write IV (initialization-vector) length & IV to encrypted file
$Crypto.GenerateIV()
$FileStreamWriter.Write([System.BitConverter]::GetBytes($Crypto.IV.Length), 0, 4)
$FileStreamWriter.Write($Crypto.IV, 0, $Crypto.IV.Length)
#Perform encryption
$Transform = $Crypto.CreateEncryptor()
$CryptoStream = New-Object System.Security.Cryptography.CryptoStream($FileStreamWriter, $Transform, [System.Security.Cryptography.CryptoStreamMode]::Write)
$FileStreamReader.CopyTo($CryptoStream)
#Close open files
$CryptoStream.FlushFinalBlock()
$CryptoStream.Close()
$FileStreamReader.Close()
$FileStreamWriter.Close()
#Delete unencrypted file
if($RemoveSource){Remove-Item -LiteralPath $File.FullName}
#Output ecrypted file
$result = Get-Item $DestinationFile
$result | Add-Member MemberType NoteProperty Name SourceFile Value $File.FullName
$result | Add-Member MemberType NoteProperty Name Algorithm Value $Algorithm
$result | Add-Member MemberType NoteProperty Name Key Value $Key
$result | Add-Member MemberType NoteProperty Name CipherMode Value $Crypto.Mode
$result | Add-Member MemberType NoteProperty Name PaddingMode Value $Crypto.Padding
$result
}
Catch
{
Write-Error $_
If($FileStreamWriter)
{
#Remove failed file
$FileStreamWriter.Close()
Remove-Item -LiteralPath $DestinationFile -Force
}
Continue
}
Finally
{
if($CryptoStream){$CryptoStream.Close()}
if($FileStreamReader){$FileStreamReader.Close()}
if($FileStreamWriter){$FileStreamWriter.Close()}
}
}
}
}
Function Unprotect-File
{
<#
.SYNOPSIS
Decrypts a file encrypted with Protect-File.
.DESCRIPTION
Decrypts a file using a provided cryptography key.
.PARAMETER FileName
File(s) to be decrypted.
.PARAMETER Key
Cryptography key as a SecureString be used for decryption.
.PARAMETER KeyAsPlainText
Cryptography key as a String to be used for decryption.
.PARAMETER CipherMode
Specifies the block cipher mode that was used for encryption.
.PARAMETER PaddingMode
Specifies the type of padding that was applied when the message data block was shorter than the full number of bytes needed for a cryptographic operation.
.PARAMETER Suffix
Suffix of the encrypted file to be removed.
.PARAMETER RemoveSource
Removes the source (encrypted) file after decrypting.
.OUTPUTS
System.IO.FileInfo. Unprotect-File will return FileInfo with the SourceFile as an added NoteProperty
.EXAMPLE
Unprotect-File 'C:\secrets.txt.AES' $key
This example decrypts C:\secrets.txt.AES using the key stored in the variable $key. The decrypted file would remove the default extension of '.AES' and the source (encrypted) file would not be removed.
.EXAMPLE
Unprotect-File 'C:\secrets.txt.Encrypted' -Algorithm DES -Key $key -Suffix '.Encrypted' -RemoveSource
This example decrypts C:\secrets.txt.Encrypted using DES and the key stored in the variable $key. The decrypted file would remove the extension of '.Encrypted' and the source (encrypted) file would be removed.
.EXAMPLE
Get-ChildItem 'C:\Files' -Recurse | Unprotect-File -Algorithm AES -Key $key -RemoveSource
This example decrypts all of the files under the C:\Files directory using the key stored in the variable $key. The decrypted files would remove the default extension of '.AES' and the source (encrypted) files would be removed.
.NOTES
Author: Tyler Siegrist
Date: 9/22/2017
#>
[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, #Assigning default value in code due to it not processing ".$Algorithm" properly when Algorithm is ValueFromPipelineByPropertyName
[Parameter()]
[Switch]$RemoveSource
)
Process
{
#Configure cryptography
try
{
if($PSCmdlet.ParameterSetName -eq 'PlainText')
{
$Key = $KeyAsPlainText | ConvertTo-SecureString -AsPlainText -Force
}
#Decrypt cryptography Key from SecureString
$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"
}
#Used to store successfully decrypted file names.
$Files = Get-Item -LiteralPath $FileName
ForEach($File in $Files)
{
#Verify file ends with supplied suffix
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)
#Get IV from file
[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
#Peform Decryption
$Transform = $Crypto.CreateDecryptor()
$CryptoStream = New-Object System.Security.Cryptography.CryptoStream($FileStreamWriter, $Transform, [System.Security.Cryptography.CryptoStreamMode]::Write)
$FileStreamReader.CopyTo($CryptoStream)
#Close open files
$CryptoStream.FlushFinalBlock()
$CryptoStream.Close()
$FileStreamReader.Close()
$FileStreamWriter.Close()
#Delete encrypted file
if($RemoveSource){Remove-Item $File.FullName}
#Output decrypted file
Get-Item $DestinationFile | Add-Member MemberType NoteProperty Name SourceFile Value $File.FullName -PassThru
}
Catch
{
Write-Error $_
If($FileStreamWriter)
{
#Remove failed file
$FileStreamWriter.Close()
Remove-Item -LiteralPath $DestinationFile -Force
}
Continue
}
Finally
{
if($CryptoStream){$CryptoStream.Close()}
if($FileStreamReader){$FileStreamReader.Close()}
if($FileStreamWriter){$FileStreamWriter.Close()}
}
}
}
}
Export-ModuleMember -Function New-CryptographyKey
Export-ModuleMember -Function Protect-File
Export-ModuleMember -Function Unprotect-File

View File

@ -19,10 +19,12 @@ The following PowerShell scripts can be found in the [Scripts/](Scripts/) subfol
* [close-windows-terminal.ps1](Scripts/close-windows-terminal.ps1) - closes Windows Terminal gracefully
* [configure-git.ps1](Scripts/configure-git.ps1) - sets up the Git configuration
* [csv-to-text.ps1](Scripts/csv-to-text.ps1) - converts the given CSV file into a text list
* [decrypt-file.ps1](Scripts/decrypt-file.ps1) - encrypts the given file
* [display-time.ps1](Scripts/display-time.ps1) - displays the current time
* [download.ps1](Scripts/download.ps1) - downloads the file/directory from the given URL
* [empty-dir.ps1](Scripts/empty-dir.ps1) - empties the given directory
* [enable-crash-dumps.ps1](Scripts/enable-crash-dumps.ps1) - enables the writing of crash dumps
* [encrypt-file.ps1](Scripts/encrypt-file.ps1) - encrypts the given file
* [generate-qrcode.ps1](Scripts/generate-qrcode.ps1) - generates a QR code
* [inspect-exe.ps1](Scripts/inspect-exe.ps1) - prints basic information of the given executable file
* [list-anagrams.ps1](Scripts/list-anagrams.ps1) - lists all anagrams of the given word

197
Scripts/decrypt-file.ps1 Executable file
View File

@ -0,0 +1,197 @@
#!/snap/bin/powershell
<#
.SYNTAX ./decrypt-file.ps1 [<path>] [<password>]
.DESCRIPTION decrypts the given file
.LINK https://github.com/fleschutz/PowerShell
.NOTES Author: Markus Fleschutz / License: CC0
#>
param([string]$Path = "", [string]$Password = "")
Set-StrictMode -Version Latest
Function Unprotect-File
{
<#
.SYNOPSIS
Decrypts a file encrypted with Protect-File.
.DESCRIPTION
Decrypts a file using a provided cryptography key.
.PARAMETER FileName
File(s) to be decrypted.
.PARAMETER Key
Cryptography key as a SecureString be used for decryption.
.PARAMETER KeyAsPlainText
Cryptography key as a String to be used for decryption.
.PARAMETER CipherMode
Specifies the block cipher mode that was used for encryption.
.PARAMETER PaddingMode
Specifies the type of padding that was applied when the message data block was shorter than the full number of bytes needed for a cryptographic operation.
.PARAMETER Suffix
Suffix of the encrypted file to be removed.
.PARAMETER RemoveSource
Removes the source (encrypted) file after decrypting.
.OUTPUTS
System.IO.FileInfo. Unprotect-File will return FileInfo with the SourceFile as an added NoteProperty
.EXAMPLE
Unprotect-File 'C:\secrets.txt.AES' $key
This example decrypts C:\secrets.txt.AES using the key stored in the variable $key. The decrypted file would remove the default extension of '.AES' and the source (encrypted) file would not be removed.
.EXAMPLE
Unprotect-File 'C:\secrets.txt.Encrypted' -Algorithm DES -Key $key -Suffix '.Encrypted' -RemoveSource
This example decrypts C:\secrets.txt.Encrypted using DES and the key stored in the variable $key. The decrypted file would remove the extension of '.Encrypted' and the source (encrypted) file would be removed.
.EXAMPLE
Get-ChildItem 'C:\Files' -Recurse | Unprotect-File -Algorithm AES -Key $key -RemoveSource
This example decrypts all of the files under the C:\Files directory using the key stored in the variable $key. The decrypted files would remove the default extension of '.AES' and the source (encrypted) files would be removed.
.NOTES
Author: Tyler Siegrist
Date: 9/22/2017
#>
[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, #Assigning default value in code due to it not processing ".$Algorithm" properly when Algorithm is ValueFromPipelineByPropertyName
[Parameter()]
[Switch]$RemoveSource
)
Process
{
#Configure cryptography
try
{
if($PSCmdlet.ParameterSetName -eq 'PlainText')
{
$Key = $KeyAsPlainText | ConvertTo-SecureString -AsPlainText -Force
}
#Decrypt cryptography Key from SecureString
$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"
}
#Used to store successfully decrypted file names.
$Files = Get-Item -LiteralPath $FileName
ForEach($File in $Files)
{
#Verify file ends with supplied suffix
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)
#Get IV from file
[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
#Peform Decryption
$Transform = $Crypto.CreateDecryptor()
$CryptoStream = New-Object System.Security.Cryptography.CryptoStream($FileStreamWriter, $Transform, [System.Security.Cryptography.CryptoStreamMode]::Write)
$FileStreamReader.CopyTo($CryptoStream)
#Close open files
$CryptoStream.FlushFinalBlock()
$CryptoStream.Close()
$FileStreamReader.Close()
$FileStreamWriter.Close()
#Delete encrypted file
if($RemoveSource){Remove-Item $File.FullName}
#Output decrypted file
Get-Item $DestinationFile | Add-Member MemberType NoteProperty Name SourceFile Value $File.FullName -PassThru
}
Catch
{
Write-Error $_
If($FileStreamWriter)
{
#Remove failed file
$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"
}
$PasswordBase64 = [System.Convert]::ToBase64String($Password)
Unprotect-File "$Path" -algorithm AES -keyAsPlainText $PasswordBase64 -removeSource
write-output "OK."
exit 0
} catch {
write-error "ERROR in line $($_.InvocationInfo.ScriptLineNumber): $($Error[0])"
exit 1
}

191
Scripts/encrypt-file.ps1 Executable file
View File

@ -0,0 +1,191 @@
#!/snap/bin/powershell
<#
.SYNTAX ./encrypt-file.ps1 [<path>] [<password>]
.DESCRIPTION encrypts the given file
.LINK https://github.com/fleschutz/PowerShell
.NOTES Author: Markus Fleschutz / License: CC0
#>
param([string]$Path = "", [string]$Password = "")
Set-StrictMode -Version Latest
Function Protect-File
{
<#
.SYNOPSIS
Encrypts a file using a symmetrical algorithm.
.DESCRIPTION
Encrypts a file using a symmetrical algorithm.
.PARAMETER FileName
File(s) to be encrypted.
.PARAMETER Key
Cryptography key as a SecureString to be used for encryption.
.PARAMETER KeyAsPlainText
Cryptography key as a String to be used for encryption.
.PARAMETER CipherMode
Specifies the block cipher mode to use for encryption.
.PARAMETER PaddingMode
Specifies the type of padding to apply when the message data block is shorter than the full number of bytes needed for a cryptographic operation.
.PARAMETER Suffix
Suffix of the encrypted file to be removed.
.PARAMETER RemoveSource
Removes the source (decrypted) file after encrypting.
.OUTPUTS
System.IO.FileInfo. Protect-File will return FileInfo with the SourceFile, Algorithm, Key, CipherMode, and PaddingMode as added NoteProperties
.EXAMPLE
Protect-File 'C:\secrets.txt' $key
This example encrypts C:\secrets.txt using the key stored in the variable $key. The encrypted file would have the default extension of '.AES' and the source (decrypted) file would not be removed.
.EXAMPLE
Protect-File 'C:\secrets.txt' -Algorithm DES -Suffix '.Encrypted' -RemoveSource
This example encrypts C:\secrets.txt with a randomly generated DES key. The encrypted file would have an extension of '.Encrypted' and the source (decrypted) file would be removed.
.EXAMPLE
Get-ChildItem 'C:\Files' -Recurse | Protect-File -Algorithm AES -Key $key -RemoveSource
This example encrypts all of the files under the C:\Files directory using the key stored in the variable $key. The encrypted files would have the default extension of '.AES' and the source (decrypted) files would be removed.
.NOTES
Author: Tyler Siegrist
Date: 9/22/2017
#>
[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)]
[ValidateSet('AES','DES','RC2','Rijndael','TripleDES')]
[String]$Algorithm = 'AES',
[Parameter(Mandatory=$false, Position=3, ParameterSetName='SecureString')]
[System.Security.SecureString]$Key = (New-CryptographyKey -Algorithm $Algorithm),
[Parameter(Mandatory=$true, Position=3, ParameterSetName='PlainText')]
[String]$KeyAsPlainText,
[Parameter(Mandatory=$false, Position=4)]
[System.Security.Cryptography.CipherMode]$CipherMode,
[Parameter(Mandatory=$false, Position=5)]
[System.Security.Cryptography.PaddingMode]$PaddingMode,
[Parameter(Mandatory=$false, Position=6)]
[String]$Suffix = ".$Algorithm",
[Parameter()]
[Switch]$RemoveSource
)
Begin
{
#Configure cryptography
try
{
if($PSCmdlet.ParameterSetName -eq 'PlainText')
{
$Key = $KeyAsPlainText | ConvertTo-SecureString -AsPlainText -Force
}
#Decrypt cryptography Key from SecureString
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Key)
$EncryptionKey = [System.Convert]::FromBase64String([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR))
$Crypto = [System.Security.Cryptography.SymmetricAlgorithm]::Create($Algorithm)
if($PSBoundParameters.ContainsKey('CipherMode')){
$Crypto.Mode = $CipherMode
}
if($PSBoundParameters.ContainsKey('PaddingMode')){
$Crypto.Padding = $PaddingMode
}
$Crypto.KeySize = $EncryptionKey.Length*8
$Crypto.Key = $EncryptionKey
}
Catch
{
Write-Error $_ -ErrorAction Stop
}
}
Process
{
$Files = Get-Item -LiteralPath $FileName
ForEach($File in $Files)
{
$DestinationFile = $File.FullName + $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)
#Write IV (initialization-vector) length & IV to encrypted file
$Crypto.GenerateIV()
$FileStreamWriter.Write([System.BitConverter]::GetBytes($Crypto.IV.Length), 0, 4)
$FileStreamWriter.Write($Crypto.IV, 0, $Crypto.IV.Length)
#Perform encryption
$Transform = $Crypto.CreateEncryptor()
$CryptoStream = New-Object System.Security.Cryptography.CryptoStream($FileStreamWriter, $Transform, [System.Security.Cryptography.CryptoStreamMode]::Write)
$FileStreamReader.CopyTo($CryptoStream)
#Close open files
$CryptoStream.FlushFinalBlock()
$CryptoStream.Close()
$FileStreamReader.Close()
$FileStreamWriter.Close()
#Delete unencrypted file
if($RemoveSource){Remove-Item -LiteralPath $File.FullName}
#Output ecrypted file
$result = Get-Item $DestinationFile
$result | Add-Member MemberType NoteProperty Name SourceFile Value $File.FullName
$result | Add-Member MemberType NoteProperty Name Algorithm Value $Algorithm
$result | Add-Member MemberType NoteProperty Name Key Value $Key
$result | Add-Member MemberType NoteProperty Name CipherMode Value $Crypto.Mode
$result | Add-Member MemberType NoteProperty Name PaddingMode Value $Crypto.Padding
$result
}
Catch
{
Write-Error $_
If($FileStreamWriter)
{
#Remove failed file
$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"
}
$PasswordBase64 = [System.Convert]::ToBase64String($Password)
Protect-File "$Path" -Algorithm AES -KeyAsPlainText $PasswordBase64 -RemoveSource
write-output "OK."
exit 0
} catch {
write-error "ERROR in line $($_.InvocationInfo.ScriptLineNumber): $($Error[0])"
exit 1
}