You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell脚本对docx、PDF、JPG等非文本文件执行CMS加解密后文件损坏问题

Got it, let's break down why your script is breaking binary files like PDFs or DOCXs—and fix it.

Why Your Binary Files Are Getting Corrupted

The core issue is how you're reading the file. Get-Content without any flags reads files as text, which tries to interpret binary data as characters using your system's default encoding. This mangles the raw byte structure of non-text files (like PDFs, DOCXs, images) before encryption, so even after decryption, the original byte data is lost forever.

Fixed Script for Both Binary & Text Files

We need to handle files as raw byte streams instead of text. Here's the adjusted script that works for all file types:

$newcert="cert-test"
# Create self-signed certificate (unchanged from your original)
New-SelfSignedCertificate -DnsName $newcert -CertStoreLocation "Cert:\CurrentUser\My" -KeyUsage KeyEncipherment,DataEncipherment,KeyAgreement -Type DocumentEncryptionCert -NotAfter (Get-Date).AddDays(30) -FriendlyName $newcert
$cert=Get-ChildItem -Path Cert:\CurrentUser\My\ | Where-Object subject -like "*$newcert*"
$thumb=$cert.thumbprint
$file = "d:\target\test\Test.pdf"
$encryptedFile = "$file.cms" # Use a separate file for encrypted output to avoid overwriting your original

# --- Encrypt the File ---
# Read the file as raw binary bytes (no text encoding conversion)
$fileBytes = [System.IO.File]::ReadAllBytes($file)
# Encrypt the byte array and save to the encrypted output file
$fileBytes | Protect-CmsMessage -To $thumb -OutFile $encryptedFile

# --- Decrypt the File ---
# Read the encrypted file's raw bytes
$encryptedBytes = [System.IO.File]::ReadAllBytes($encryptedFile)
# Decrypt and write the original byte structure back to disk
$decryptedBytes = $encryptedBytes | Unprotect-CmsMessage -To $thumb
[System.IO.File]::WriteAllBytes($file, $decryptedBytes) # Overwrites original; adjust path if you want a separate decrypted file
Key Changes Explained
  • Reading raw bytes: Instead of Get-Content, we use [System.IO.File]::ReadAllBytes() to grab every byte of the original file without any text encoding logic. This preserves the exact structure of binary files.
  • Separate encrypted file: I added a .cms extension to the encrypted output to avoid accidentally overwriting your original file during testing—you can tweak this if you prefer, but it's a safer approach.
  • Writing raw bytes: After decryption, [System.IO.File]::WriteAllBytes() ensures we write the decrypted byte array back exactly as it was, restoring the original file structure.
For PowerShell 6+ Users (Idiomatic Alternative)

If you're using PowerShell Core 6 or later, you can use native PowerShell cmdlets with the -AsByteStream flag instead of .NET methods:

# Encrypt with PowerShell 6+
Get-Content $file -AsByteStream | Protect-CmsMessage -To $thumb -OutFile $encryptedFile

# Decrypt with PowerShell 6+
Get-Content $encryptedFile -AsByteStream | Unprotect-CmsMessage -To $thumb | Set-Content $file -AsByteStream

The -AsByteStream flag tells PowerShell to handle the file as raw binary data, skipping any text encoding that would break non-text files.

内容的提问来源于stack exchange,提问作者chaz stone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 19:12:40