英文:
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>
<!-- language-all: sh -->
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['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
}
}
- 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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论