将 Powershell Securestring 传递给 7zip,但之后无法解压缩存档

Passing Powershell Securestring to 7zip, but archive cannot be unpacked afterwards

备份我的数据的 Powershell 脚本从命令行读取密码并将其传递给 7zip (7z):

....
$pw = Read-Host -assecurestring -Prompt 'Input Backup Master Passphrase: '
$pw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw))
....
& 'C:\Program Files-Zipz.exe' a -v900M -t7z -mhe=on -mx=9 -p$pw $target/myarchive.7z $src

但是当我在 7zip (GUI) 中打开存档时,它会显示密码提示,输入密码后它会显示一个文件(还是一个 7zip 文件),该文件也已加密,但不响应密码。

当我在另一个 Powershell 脚本中提取文件时,它工作正常。

# $pw is read again from commandline via Read-Host....&PtrToStringAuto
& 'C:\Program Files-Zipz.exe' x -p$pw $target/myarchive.7z

为什么提取只能在 CLI 上进行,而不能通过 GUI 进行?

经过多次实验(为了科学!),我发现 7z 线没有按预期工作。在原始代码中, -p$pw 实际上将密码设置为文字 $pw.

快速而肮脏的方法是使用 Invoke-Expression 代替:

$inpw = Read-Host -assecurestring -Prompt 'Input Backup Master Passphrase: '
$zpw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($inpw))

$archive = "myarchive.7z"
$src = "testfile.txt"
# using a string formatter to avoid a mess of escaping characters 
Invoke-Expression ('& "{0}" a -v900M -t7z -mhe=on -mx=9 -p{1} {2} {3}' -f 'C:\Program Files-Zipz.exe', $zpw, $archive, $src)

但是,这与字符串插值和其他 security/data 问题有关。您还可以查看 Start-Process,或使用 .NET Process.Start 方法进行更多控制。