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

在Windows PowerShell 5.1中编写JavaScriptConverter实现带属性混淆的PSCustomObject序列化与反序列化

在Windows PowerShell 5.1中编写JavaScriptConverter实现带属性混淆的PSCustomObject序列化与反序列化

当然可以在PowerShell 5.1里实现这个需求!我经常用自定义转换器处理这类敏感属性的序列化问题,下面就一步步演示如何实现,完全贴合你的示例场景。

首先,我们需要依赖System.Web.Extensions程序集里的JavaScriptConverter抽象类,先加载这个程序集:

Add-Type -AssemblyName System.Web.Extensions

接下来,定义一个继承自JavaScriptConverter的PowerShell类,它负责处理Password属性的加密(混淆)和解密(还原)逻辑:

class SecurePasswordConverter : System.Web.Script.Serialization.JavaScriptConverter {
    # 指定转换器支持处理的类型,这里先针对PSCustomObject
    [System.Collections.Generic.IEnumerable[Type]] get_SupportedTypes() {
        return [Type[]]@([PSCustomObject])
    }

    # 序列化方法:把对象转成JSON可识别的字典,同时加密Password
    [System.Collections.Generic.IDictionary[string, object]] Serialize([object]$obj, [System.Web.Script.Serialization.JavaScriptSerializer]$serializer) {
        $outputDict = [System.Collections.Generic.Dictionary[string, object]]::new()
        $psObject = [PSCustomObject]$obj

        # 遍历对象所有属性
        foreach ($prop in $psObject.PSObject.Properties) {
            if ($prop.Name -eq 'Password') {
                # 把明文密码用DPAPI加密后转成Base64字符串(和你示例里的SecureString格式一致)
                $encryptedBytes = [System.Security.Cryptography.ProtectedData]::Protect(
                    [System.Text.Encoding]::Unicode.GetBytes($prop.Value),
                    $null,
                    [System.Security.Cryptography.DataProtectionScope]::CurrentUser
                )
                $outputDict['Password'] = [System.Convert]::ToBase64String($encryptedBytes)
            } else {
                # 其他属性直接保留原内容
                $outputDict[$prop.Name] = $prop.Value
            }
        }
        return $outputDict
    }

    # 反序列化方法:把JSON字典转成对象,同时还原Password
    [object] Deserialize([System.Collections.Generic.IDictionary[string, object]$dict, [Type]$type, [System.Web.Script.Serialization.JavaScriptSerializer]$serializer) {
        $resultObj = [PSCustomObject]::new()
        foreach ($key in $dict.Keys) {
            if ($key -eq 'Password') {
                # 把Base64加密字符串解密回明文
                $encryptedBytes = [System.Convert]::FromBase64String($dict[$key])
                $decryptedBytes = [System.Security.Cryptography.ProtectedData]::Unprotect(
                    $encryptedBytes,
                    $null,
                    [System.Security.Cryptography.DataProtectionScope]::CurrentUser
                )
                $plainPassword = [System.Text.Encoding]::Unicode.GetString($decryptedBytes)
                # 如果需要保留SecureString类型,替换成下面这行即可
                # $plainPassword = ConvertTo-SecureString -String $plainPassword -AsPlainText -Force
                $resultObj | Add-Member -MemberType NoteProperty -Name $key -Value $plainPassword
            } else {
                $resultObj | Add-Member -MemberType NoteProperty -Name $key -Value $dict[$key]
            }
        }
        return $resultObj
    }
}

现在测试这个转换器的效果,完全匹配你的示例场景:

# 创建测试对象
$testUser = [PSCustomObject]@{
    Username = "foo"
    Password = "bar"
}

# 实例化序列化器并注册我们的自定义转换器
$serializer = [System.Web.Script.Serialization.JavaScriptSerializer]::new()
$serializer.RegisterConverters([System.Web.Script.Serialization.JavaScriptConverter[]]@([SecurePasswordConverter]::new()))

# 序列化对象到JSON字符串
$jsonResult = $serializer.Serialize($testUser)
Write-Host "序列化后的JSON内容:`n$jsonResult"

# 把JSON写入磁盘文件
$jsonResult | Out-File -Path ".\user_config.json" -Encoding UTF8

# 从文件读取JSON并反序列化
$jsonFromFile = Get-Content -Path ".\user_config.json" -Raw
$restoredUser = $serializer.Deserialize($jsonFromFile, [PSCustomObject])

Write-Host "`n反序列化后的对象:"
$restoredUser
Write-Host "`n还原后的明文密码:$($restoredUser.Password)"

几个关键细节说明:

  • 这里用的是Windows DPAPI加密,加密后的内容只能在当前用户账户下解密,安全性比单纯转SecureString更高(其实ConvertFrom-SecureString底层也是用DPAPI),完全符合你示例里的加密格式。
  • 如果你想更严谨,不想让转换器处理所有PSCustomObject,可以定义一个自定义类(比如class User { [string]$Username; [string]$Password }),然后把转换器的SupportedTypes改成[Type[]]@([User])即可。
  • 反序列化时,你可以选择把密码还原成明文或者保持SecureString类型,根据实际需求调整代码即可。

备注:内容来源于stack exchange,提问作者Peyre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 09:52:43