我能够使用Windows 10(PowerShell版本5.1)使用此脚本here成功地AES加密文件。
当我尝试在Windows 7,PowerShell v2.0上运行它时,出现错误:
New-CryptographyKey : You cannot call a method on a null-valued expression. At C:\Users\IEUser\Desktop\enc.ps1:399 char:27 + $key = New-CryptographyKey <<<< -AsPlainText + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,New-CryptographyKey Protect-File : Cannot bind argument to parameter 'KeyAsPlainText' because it is an empty string. At C:\Users\IEUser\Desktop\enc.ps1:401 char:77 + Protect-File -FileName "$env:userprofile/Desktop/secret.txt" -KeyAsPlainText <<<< $key + CategoryInfo : InvalidData: (:) [Protect-File], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Protect-File
我如何使其工作?还是有使用Powershell进行AES文件加密的另一种交叉兼容解决方案?
编辑:
我可能已经找到了使用openSSL的解决方案,但是我仍然尝试@Mike Twc的解决方案,得到了以下输出:
PS C:\Users\IEUser\Desktop> .\bouncy.ps1
TEST:
message: Some secret message
key: 9JODwRWWHp6+uACUiydFXNXPmWDHbcObhgqR/cvZ9zg=
IV (base64): U29tZV9QYXNzd29yZA==
IV (utf8): Some_Password
message bytes: 83 111 109 101 32 115 101 99 114 101 116 32 109 101 115 115 97 10
3 101
encrypted message bytes: 178 172 14 98 228 38 129 136 217 25 129 96 46 177 75 62
50 5 190 46 51 108 81 38 90 74 197 166 44 96 120 252
encrypted message: sqwOYuQmgYjZGYFgLrFLPjIFvi4zbFEmWkrFpixgePw=
decrypted bytes: 83 111 109 101 32 115 101 99 114 101 116 32 109 101 115 115 97
103 101 0 0 0 0 0 0 0 0 0 0 0 0 0
decrypted message: Some secret message
答案 0 :(得分:0)
您使用的模块至少需要PowerShell v3,否则该语句
$Crypto = [System.Security.Cryptography.SymmetricAlgorithm]::Create($Algorithm)
在您尝试调用的函数中不会创建算法对象,这反过来会导致
$Crypto.GenerateKey()
因观察到的错误而失败。
将Windows 7系统升级到PowerShell v3或更高版本。
答案 1 :(得分:0)
根据链接到的代码的源信息(即您正在使用的代码),并不是在设计PowerShell v2时才考虑的。因此,应该预见到它会失败的事实,因为如果有内存可用,则在PowerShellv3之前不会引入Export-ModuleMember。
Get-Command -Name Export-moduleMember
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Export-ModuleMember 3.0.0.0 Microsoft.PowerShell.Core
我的环境中的任何地方都没有PowerShellv2可以进行圣检查。
所以,就这个。
我如何使其工作?
..将您的PowerShell版本升级到3-5倍。
至此...
另一个使用AES文件加密的交叉兼容解决方案 Powershell?
PowerShell Core(PowerShell v6)甚至是PowerShell的唯一跨平台版本。 如果您要使用的是该模块的跨平台版本,则由作者提供还是由您编写。
如果您要使用通用的跨平台AES工具(即使您指向的链接也仅是Windows-因此,如果您需要跨平台Win / OSX / Linux,则无论如何将无法正常工作),那真的不是PowerShell问题但是有软件推荐,还有一个单独的委员会来回答这些问题。 Software Recommendations StackExchange,但是使用PowerShell时您可以使用PGP。
如果要说的是适用于Windows PowerShell所有版本的AES文件加密版本,则需要使用.Net命名空间。具体地说,NET的FileStream和CryptoStream类通过此脚本下载演示了使用AES加密的整个文件。
PowerShell Encryption Examples 5种不同技术的示例,可用于使用PowerShell安全加密(并在大多数情况下共享)机密数据。
具体示例3
或使用此模块。
Share encrypted data between users and computers with PowerShell
附加的zip文件包含一个模块,该模块可轻松使用PowerShell加密数据,以便其他计算机上的其他授权用户可以解密该数据。它通过利用数字证书来做到这一点。
答案 2 :(得分:0)
您可以尝试使用BouncyCastle库。以下是该库的AES加密/解密实现。它在版本2模式下对我有效。
从此处下载最新的编译程序集(BouncyCastle.Crypto.dll): https://www.bouncycastle.org/csharp/index.html
将该dll提取到任何文件夹(例如C:\ temp),右键单击它,然后选中“取消阻止”
运行以下代码:
Add-Type -path "C:\stack\BouncyCastle.Crypto.dll"
$secRandom = new-object Org.BouncyCastle.Security.SecureRandom
$message = "Some secret message"
$messageBytes = [System.Text.Encoding]::UTF8.GetBytes($message)
# if using files do this:
# $messageBytes = [System.IO.File]::ReadAllBytes("C:\stack\out.txt")
#==== Key generation =====#
$keyBytes = New-Object byte[] 32
$secRandom.NextBytes($keyBytes)
#$generator = [Org.BouncyCastle.Security.GeneratorUtilities]::GetKeyGenerator("AES")
$generator = New-Object Org.BouncyCastle.Crypto.CipherKeyGenerator
$keyGenParam = new-object Org.BouncyCastle.Crypto.KeyGenerationParameters $keyBytes, 256
$generator.Init($keyGenParam)
$key = $generator.GenerateKey()
#or retreive from base64 string:
$key = [System.Convert]::FromBase64String("9JODwRWWHp6+uACUiydFXNXPmWDHbcObhgqR/cvZ9zg=")
#==== initialization vector (optional) =====#
#IV is a byte array, should be same as AES block size. By default 128 bit or 16 bytes (or less)
$IV = New-Object byte[] 16
# below are some random IVs to play around, if IV parameter is not provided by user just keep it is array of 0s
$secRandom.NextBytes($IV) | Out-Null #random generated 16 bytes
$IV = [System.Text.Encoding]::UTF8.GetBytes("Some_Password") #or use some random phrase
#==== Cipher set up =====#
#specify cipher type (typically CFB or CBC) and padding (use NOPADDING to skip). Check all possible values:
#https://github.com/neoeinstein/bouncycastle/blob/master/crypto/src/security/CipherUtilities.cs
$cipher = [Org.BouncyCastle.Security.CipherUtilities]::GetCipher("AES/CFB/PKCS7")
$aesKeyParam = [Org.BouncyCastle.Security.ParameterUtilities]::CreateKeyParameter("AES", $key)
$keyAndIVparam = New-Object Org.BouncyCastle.Crypto.Parameters.ParametersWithIV $aesKeyParam, $IV
#==== Encrypt =====#
#$cipher.Init($true,$aesKeyParam)
$cipher.Init($true,$keyAndIVparam)
$dataSize = $cipher.GetOutputSize($messageBytes.Length)
$encMessageBytes = New-Object byte[] $dataSize
$len = $cipher.ProcessBytes($messageBytes , 0, $messageBytes.Length, $encMessageBytes, 0)
$cipher.DoFinal($encMessageBytes, $len) | Out-Null
$encMessage = [System.Convert]::ToBase64String($encMessageBytes)
#if using files
#[System.IO.File]::WriteAllText("C:\stack\out.txt.aes", $encMessage)
#$encMessageBytes = [System.Convert]::FromBase64String([System.IO.File]::ReadAllText("C:\stack\out.txt.aes"))
#==== Decrypt =====#
#$cipher.Init($false,$aesKeyParam)
$cipher.Init($false,$keyAndIVparam)
$dataSize = $cipher.GetOutputSize($encMessageBytes.Length)
$decMessageBytes = New-Object byte[] $dataSize
$len = $cipher.ProcessBytes($encMessageBytes , 0, $encMessageBytes.Length, $decMessageBytes, 0)
$cipher.DoFinal($decMessageBytes, $len) | Out-Null
$decMessage = [System.Text.Encoding]::UTF8.GetString($decMessageBytes).Trim([char]0)
#==== TEST =====#
Write-Host "`nTEST:`n"
Write-Host "message: $message"
Write-Host "key: $([System.Convert]::ToBase64String($key))"
Write-Host "IV (base64): $([System.Convert]::ToBase64String($IV))"
Write-Host "IV (utf8): $([System.Text.Encoding]::UTF8.GetString($IV))"
Write-Host "message bytes: $messageBytes"
Write-Host "encrypted message bytes: $encMessageBytes"
Write-Host "encrypted message: $encMessage"
Write-Host "decrypted bytes: $decMessageBytes"
Write-Host "decrypted message: $decMessage"