关于本文
本文使用生成式 AI 辅助的自动化流程创建。我们确认了 .NET 的 ProtectedData 规范,并将其整理为从 PowerShell 调用 Windows DPAPI 以保护秘密字符串的技巧。验证状态:📘 已确认官方API・已实现PowerShell示例・Windows PowerShell 5.1 实机未验证
不要将秘密字符串放在明文文件中 — 从 PowerShell 调用 Windows DPAPI
我们当然希望避免将 API 密钥或密码直接写在配置文件中。但是,对于个人电脑上的小型自动化任务,又不想准备庞大的秘密管理基础设施。在这种情况下,Windows 提供了一种名为 DPAPI 的机制。
在 PowerShell 中,可以通过使用 .NET 的 System.Security.Cryptography.ProtectedData 来调用它。
使用 CurrentUser 作用域进行保护
# CurrentUser 用于指定与“当前 Windows 用户”绑定并进行保护。
$scope = [System.Security.Cryptography.DataProtectionScope]::CurrentUser
# 由于 DPAPI 接收字节数组,因此将字符串转换为 UTF-8。
# 这里使用的是用于说明的虚拟字符串。
$bytes = [Text.Encoding]::UTF8.GetBytes("dummy-secret")
# ProtectedData.Protect() 会调用 Windows DPAPI。
# 第二个参数 $null 指定不使用附加熵。
$protected = [System.Security.Cryptography.ProtectedData]::Protect(
$bytes,
$null,
$scope
)
# 加密后不是字符串而是字节数组,因此按二进制直接保存。
[IO.File]::WriteAllBytes(".secret.bin", $protected)
在此示例中,我们使用了与 Windows 当前用户绑定的作用域。保存的 secret.bin 并不是明文字符串。
但是,这并不意味着“秘密管理就此万无一失”
CurrentUser 可以在相同的 Windows 用户上下文中进行解密。换句话说,它并不是一个能够防范终端设备或用户账户本身遭到侵害的万能机制。
此外,如果仅备份加密文件,而丢失了用户配置文件或 DPAPI 所需的信息,则可能无法进行解密。
它的适用场景:
个人电脑上的辅助脚本
希望避免明文保存的小规模自动化
理解 Windows 秘密保护机制的教材
从这些用途开始了解会比较容易理解。
不要将秘密写入命令行
如果像 -Secret "本物のパスワード" 那样作为参数传入,则可能会留在历史记录或日志中。在 GitHub 的示例中,我们采用了通过 Read-Host -AsSecureString 输入,并在可能范围内清除转换所用内存的形式。
flowchart LR
A[秘密文字列] --> B[ProtectedData.Protect]
B --> C[暗号化バイト列]
C --> D[ファイル保存]
D --> E[同じユーザーでUnprotect]


コメント