使用OpenSSL签名文件夹或文件内容出错,求PowerShell解决办法
Hey Jose, let's tackle your two main issues one by one—first getting the script to traverse subfolders, then figuring out how to handle folder "signing" since OpenSSL doesn't work directly on folders.
1. Fixing Subfolder File Traversal & Avoiding Permission Errors
The permission denied error happens because your current script is probably trying to pass folders to OpenSSL, which expects a file. To fix this, we'll use PowerShell's Get-ChildItem with parameters to only grab files (not folders) from all subfolders.
Here's the key adjustment:
# Replace your file retrieval line with this $allFiles = Get-ChildItem -Path $USBPath -Recurse -File
The -Recurse flag tells PowerShell to dive into all subfolders, and -File filters out folders entirely—so you won't accidentally pass a folder to OpenSSL anymore.
2. Handling Folder "Signing" (Since OpenSSL Can't Sign Folders Directly)
OpenSSL is designed to sign file content, not directory structures. You have two common options to handle folders:
Option A: Sign a Compressed Version of the Folder
Zip or tar the folder first, then sign the compressed file. This way, anyone can verify the signature, extract the folder, and confirm its contents match.
# Example: Zip a folder and sign it $folderToSign = "C:\USB\MyFolder" $zipPath = "$folderToSign.zip" # Create zip (PowerShell 5.1+ has Compress-Archive built-in) Compress-Archive -Path $folderToSign -DestinationPath $zipPath -Force # Sign the zip file with your OpenSSL command & C:\openssl\openssl.exe dgst -sha256 -sign $PriKey -out "$zipPath.sha256" -passin pass:<password> $zipPath
Option B: Sign a Hash List of the Folder's Contents
Generate a text file that lists every file in the folder along with its SHA256 hash, then sign that list. This lets others verify individual files and the directory structure.
# Example: Generate and sign a folder hash list $folderPath = "C:\USB\MyFolder" $hashListPath = "$folderPath\folder_hashes.txt" # Generate hash list for all files in the folder Get-ChildItem -Path $folderPath -Recurse -File | ForEach-Object { $fileHash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash "$($_.FullName): $fileHash" | Out-File -FilePath $hashListPath -Append -Encoding UTF8 } # Sign the hash list file & C:\openssl\openssl.exe dgst -sha256 -sign $PriKey -out "$hashListPath.sha256" -passin pass:<password> $hashListPath
Full Working Script Example
Here's a complete script that handles all files in the USB drive (including subfolders) and gives you an option to process folders using the hash list method:
# Set your variables here $USBPath = "D:\" # Replace with your USB drive letter/path $PriKey = "C:\path\to\your\private.key" # Replace with your private key path $password = "your-actual-password" # Replace with your password # 1. Sign all files (including subfolders) Get-ChildItem -Path $USBPath -Recurse -File | ForEach-Object { $file = $_ $outputSignaturePath = Join-Path -Path $file.DirectoryName -ChildPath "$($file.Name).sha256" # Run OpenSSL command & C:\openssl\openssl.exe dgst -sha256 -sign $PriKey -out $outputSignaturePath -passin pass:$password $file.FullName # Optional: Print progress Write-Host "Signed file: $($file.FullName)" } # 2. Optional: Process folders by generating and signing hash lists Get-ChildItem -Path $USBPath -Recurse -Directory | ForEach-Object { $folder = $_ $hashListPath = Join-Path -Path $folder.FullName -ChildPath "folder_hashes.txt" $signaturePath = "$hashListPath.sha256" # Generate hash list Get-ChildItem -Path $folder.FullName -Recurse -File | ForEach-Object { $fileHash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash "$($_.FullName): $fileHash" | Out-File -FilePath $hashListPath -Append -Encoding UTF8 } # Sign the hash list & C:\openssl\openssl.exe dgst -sha256 -sign $PriKey -out $signaturePath -passin pass:$password $hashListPath Write-Host "Generated and signed hash list for folder: $($folder.FullName)" }
Quick Notes
- Always use
Join-Pathinstead of manually concatenating paths with\—it avoids errors with trailing/leading slashes. - The
&before the OpenSSL command tells PowerShell to run the external executable. - If you don't need to handle folders, just remove the second section of the script.
Hope this gets you sorted out!
内容的提问来源于stack exchange,提问作者Jose Lopez

