JavaScriptConverter 用于在 JSON 中序列化/反序列化数据的 PowerShell 代码。

huangapple go评论68阅读模式
英文:

powershell, write a JavaScriptConverter to serialize/deserialize data in JSON

问题

I have a PSCustomObject that I need to serialize on disk in JSON but one property needs to be obfuscated before being written and of course, deobfuscated when read later on.

我有一个PSCustomObject,我需要将其序列化为JSON并在写入之前对其中一个属性进行混淆,当以后读取时需要解混淆。

I found that JavaScriptSerializer could do the trick when customized with a JavaScriptConverter (both ways, read and write), but all the examples I find are in C#, for example this very interesting thread

我发现JavaScriptSerializer可以通过使用JavaScriptConverter进行定制来实现此目标(读取和写入都可以),但我找到的所有示例都是使用C#编写的,例如这个非常有趣的帖子

Is it possible to write such a JavaScriptConverter in PowerShell (maybe using a Class in place of the PSCustomObject)?

是否可能在PowerShell中编写这样的JavaScriptConverter(也许可以使用类来代替PSCustomObject)?

As a matter of example, let's say that the PSCustomObject is @{Username:"foo";Password:"bar"} and that I want the JSON file to be:

例如,假设PSCustomObject是@{Username:"foo";Password:"bar"},而我希望JSON文件如下:

{
    "Username": "foo",
    "Password": "01000000d08c9ddf0115d1118c7a00c04fc297eb01000000b83de0765b9a2a4088e073b1166fd67e0000000002000000000003660000c000000010000000790fcfe1dce43342e8d444757f46c8d50000000004800000a0000000100000002d0020ca9088b3d85b27f597847a3dc908000000ca11862bdb95757b1400002e326a0041e039d8ff9c41ff46ec24c1f"
}

with Password in the JSON file being the SecureString version of the original password property. The need is for Windows PowerShell 5.1 only, not PowerShell 6+.

在JSON文件中,Password将是原始password属性的SecureString版本。此需求仅适用于Windows PowerShell 5.1,而不适用于PowerShell 6+。

英文:

I have a PSCustomObject that I need to serialize on disk in JSON but one property needs to be obfuscated before being written and of course, deobfuscated when read later on.

I found that JavaScriptSerializer could do the trick when customized with a JavaScriptConverter (both ways, read and write), but all the examples I find are in C#, for example this very interesting thread

is it possible to write such a JavaScriptConverter in Powershell (maybe using a Class in place of the PSCustomObject)?

as a matter of example, let say that the PSCustomObject is @{Username:"foo";Password:"bar"} and that I want the JSON file to be

{
    "Username": "foo",
    "Password": "01000000d08c9ddf0115d1118c7a00c04fc297eb01000000b83de0765b9a2a4088e073b1166fd67e0000000002000000000003660000c000000010000000790fcfe1dce43342e8d444757f46c8d50000000004800000a0000000100000002d0020ca9088b3d85b27f597847a3dc908000000ca11862bdb95757b140000002802e326a0041e039d8ff9c41ff46ec24c1f"
}

with Password in the JSON file being the SecureString version of the original password property. the need is for Windows Powershell 5.1 only, not powershell 6+

答案1

得分: 1

以下是代码的翻译部分:

<!-- language-all: sh -->

PowerShell 中的实现大致如下,虽然不是完美的,但可能对您有所帮助。请注意,此示例侧重于对 [`PSCredential`](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.pscredential?view=powershellsdk-7.3.0) 对象的序列化和反序列化,而不是 `PSCustomObject`。

- 类

```powershell
Add-Type -AssemblyName System.Web.Extensions

class SecureStringConverter : System.Web.Script.Serialization.JavaScriptConverter {
    SecureStringConverter() { }

    [System.Collections.Generic.IEnumerable[Type]] get_SupportedTypes() {
        return [type[]] [pscredential]
    }

    [object] Deserialize(
        [System.Collections.Generic.IDictionary[string, object]] $dict,
        [type] $type,
        [System.Web.Script.Serialization.JavaScriptSerializer] $serializer
    ) {
        return [pscredential]::new(
            $dict['UserName'],
            [System.Management.Automation.PSSerializer]::Deserialize($dict['Password'])
        )
    }

    [System.Collections.Generic.IDictionary[string, object]] Serialize(
        [object] $object,
        [System.Web.Script.Serialization.JavaScriptSerializer] $serializer
    ) {
        $dict = [System.Collections.Generic.Dictionary[string, object]]::new()
        $dict['UserName'] = $object.UserName
        $dict['Password'] = [System.Management.Automation.PSSerializer]::Serialize($object.Password)
        return $dict
    }
}
  • 序列化
$obj = [pscredential]::new(
    'SomeUser',
    (ConvertTo-SecureString 'bar' -AsPlainText -Force))

$serializer = [Web.Script.Serialization.JavaScriptSerializer]::new()
$serializer.RegisterConverters(
    [System.Web.Script.Serialization.JavaScriptConverter[]]@(
    [SecureStringConverter]::new()))

$json = $serializer.Serialize($obj)
  • 反序列化
$deserialized = $serializer.Deserialize($json, [pscredential])
$deserialized.GetNetworkCredential().Password # 应该是 `bar`

<details>
<summary>英文:</summary>

&lt;!-- language-all: sh --&gt;

The implementation in PowerShell would look more or less like this, clearly not perfect but might help you get started. Note, this example focuses on serialization and deserialization of a [`PSCredential`](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.pscredential?view=powershellsdk-7.3.0) object, not a `PSCustomObject`.

- Class

Add-Type -AssemblyName System.Web.Extensions

class SecureStringConverter : System.Web.Script.Serialization.JavaScriptConverter {
SecureStringConverter() { }

[System.Collections.Generic.IEnumerable[Type]] get_SupportedTypes() {
    return [type[]] [pscredential]
}

[object] Deserialize(
    [System.Collections.Generic.IDictionary[string, object]] $dict,
    [type] $type,
    [System.Web.Script.Serialization.JavaScriptSerializer] $serializer
) {
    return [pscredential]::new(
        $dict[&#39;UserName&#39;],
        [System.Management.Automation.PSSerializer]::Deserialize($dict[&#39;Password&#39;])
    )
}

[System.Collections.Generic.IDictionary[string, object]] Serialize(
    [object] $object,
    [System.Web.Script.Serialization.JavaScriptSerializer] $serializer
) {
    $dict = [System.Collections.Generic.Dictionary[string, object]]::new()
    $dict[&#39;UserName&#39;] = $object.UserName
    $dict[&#39;Password&#39;] = [System.Management.Automation.PSSerializer]::Serialize($object.Password)
    return $dict
}

}


- Serialization

$obj = [pscredential]::new(
'SomeUser',
(ConvertTo-SecureString 'bar' -AsPlainText -Force))

$serializer = [Web.Script.Serialization.JavaScriptSerializer]::new()
$serializer.RegisterConverters(
[System.Web.Script.Serialization.JavaScriptConverter[]]@(
[SecureStringConverter]::new()))

$json = $serializer.Serialize($obj)


- Deserialization

$deserialized = $serializer.Deserialize($json, [pscredential])
$deserialized.GetNetworkCredential().Password # Should be bar


</details>



huangapple
  • 本文由 发表于 2023年3月20日 23:48:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75792451.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定