替换 JSON 树中未知位置的 JSON 个对象
Replace JSON objects in unknown positions inside a JSON tree
在 JSON 文件中,我需要使用命令行工具 jq
将加密值替换为明文值作为初始化过程。然后,应用程序将使用自己的密钥重新加密这些值,覆盖明文值。加密值表示为“$crypto”对象,包含有关加密方法和使用的密钥的信息,如下所示:
{
"$crypto" : {
"type" : "x-simple-encryption",
"value" : {
"cipher" : "AES/CBC/PKCS5Padding",
"stableId" : "someId",
"salt" : "4J5ckE6+JaS8TLqAN4073g==",
"data" : "vBeHAPJXLl+X/8Enp9vxMA==",
"keySize" : 16,
"purpose" : "someDescription",
"iv" : "N2xCe5RiJibHv9hLY+OduA==",
"mac" : "VoOo1BKptwfqIJeSOb/qGA=="
}
}
}
这些“$crypto”对象可以位于 JSON 结构中的任何位置。示例输入文档如下所示:
{
"unknownKey1" : {
"unknownKey2" : {
"name" : "JWT_SESSION",
"properties" : {
"maxTokenLifeMinutes" : 120,
"tokenIdleTimeMinutes" : 30
}
},
"unknownKey3" : [
{
"unknownKey4" : "STATIC_USER",
"unknownKey5" : {
"unknownKey6" : "internal/user",
"unknownKey7" : "anonymous",
"unknownKey8" : {
"$crypto" : {
"type" : "x-simple-encryption",
"value" : {
"cipher" : "AES/CBC/PKCS5Padding",
"stableId" : "someId",
"salt" : "4J5ckE6+JaS8TLqAN4073g==",
"data" : "vBeHAPJXLl+X/8Enp9vxMA==",
"keySize" : 16,
"purpose" : "someDescription",
"iv" : "N2xCe5RiJibHv9hLY+OduA==",
"mac" : "VoOo1BKptwfqIJeSOb/qGA=="
}
}
}
},
"enabled" : true
}
]
}
}
所以 "unknownKey8" 的值被加密了。我需要该文档如下所示:
{
"unknownKey1" : {
"unknownKey2" : {
"name" : "JWT_SESSION",
"properties" : {
"maxTokenLifeMinutes" : 120,
"tokenIdleTimeMinutes" : 30
}
},
"unknownKey3" : [
{
"unknownKey4" : "STATIC_USER",
"unknownKey5" : {
"unknownKey6" : "internal/user",
"unknownKey7" : "anonymous",
"unknownKey8" : "clearTextValue"
},
"enabled" : true
}
]
}
}
我已经能够使用以下命令在输入文件中找到加密对象:
cat input.json | jq 'paths | select(.[-1] == "$crypto")'
[
"unknownKey1",
"unknownKey3",
0,
"unknownKey5",
"unknownKey8",
"$crypto"
]
但是我无法在执行替换方面取得有意义的进展。
下面进行文中描述的替换。沿
行的调用
jq --arg cleartext "clearTextValue" -f decrypt.jq sample.json
假设。如果您的 jq 没有 walk/1
,则要么升级到 jq 1.6,要么在调用之前包含其 def(google 搜索词:jq def walk builtin.jq
)。
# input is assumed to be an object
def decrypt($value):
with_entries(if .value|type == "object"
then with_entries(if .value | (type == "object" and has("$crypto"))
then .value = $value else . end)
else . end) ;
walk(if type == "object" then decrypt($cleartext) else . end)
作为已接受答案的补充,如果使用 jq v1.5,请将其用作 decrypt.jq
# input is assumed to be an object
def decrypt($value):
with_entries(if .value|type == "object"
then with_entries(if .value | (type == "object" and has("$crypto"))
then .value = $value else . end)
else . end) ;
# walk was added after the release of jq@1.5
def walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;
walk(if type == "object" then decrypt($cleartext) else . end)
在 JSON 文件中,我需要使用命令行工具 jq
将加密值替换为明文值作为初始化过程。然后,应用程序将使用自己的密钥重新加密这些值,覆盖明文值。加密值表示为“$crypto”对象,包含有关加密方法和使用的密钥的信息,如下所示:
{
"$crypto" : {
"type" : "x-simple-encryption",
"value" : {
"cipher" : "AES/CBC/PKCS5Padding",
"stableId" : "someId",
"salt" : "4J5ckE6+JaS8TLqAN4073g==",
"data" : "vBeHAPJXLl+X/8Enp9vxMA==",
"keySize" : 16,
"purpose" : "someDescription",
"iv" : "N2xCe5RiJibHv9hLY+OduA==",
"mac" : "VoOo1BKptwfqIJeSOb/qGA=="
}
}
}
这些“$crypto”对象可以位于 JSON 结构中的任何位置。示例输入文档如下所示:
{
"unknownKey1" : {
"unknownKey2" : {
"name" : "JWT_SESSION",
"properties" : {
"maxTokenLifeMinutes" : 120,
"tokenIdleTimeMinutes" : 30
}
},
"unknownKey3" : [
{
"unknownKey4" : "STATIC_USER",
"unknownKey5" : {
"unknownKey6" : "internal/user",
"unknownKey7" : "anonymous",
"unknownKey8" : {
"$crypto" : {
"type" : "x-simple-encryption",
"value" : {
"cipher" : "AES/CBC/PKCS5Padding",
"stableId" : "someId",
"salt" : "4J5ckE6+JaS8TLqAN4073g==",
"data" : "vBeHAPJXLl+X/8Enp9vxMA==",
"keySize" : 16,
"purpose" : "someDescription",
"iv" : "N2xCe5RiJibHv9hLY+OduA==",
"mac" : "VoOo1BKptwfqIJeSOb/qGA=="
}
}
}
},
"enabled" : true
}
]
}
}
所以 "unknownKey8" 的值被加密了。我需要该文档如下所示:
{
"unknownKey1" : {
"unknownKey2" : {
"name" : "JWT_SESSION",
"properties" : {
"maxTokenLifeMinutes" : 120,
"tokenIdleTimeMinutes" : 30
}
},
"unknownKey3" : [
{
"unknownKey4" : "STATIC_USER",
"unknownKey5" : {
"unknownKey6" : "internal/user",
"unknownKey7" : "anonymous",
"unknownKey8" : "clearTextValue"
},
"enabled" : true
}
]
}
}
我已经能够使用以下命令在输入文件中找到加密对象:
cat input.json | jq 'paths | select(.[-1] == "$crypto")'
[
"unknownKey1",
"unknownKey3",
0,
"unknownKey5",
"unknownKey8",
"$crypto"
]
但是我无法在执行替换方面取得有意义的进展。
下面进行文中描述的替换。沿
行的调用jq --arg cleartext "clearTextValue" -f decrypt.jq sample.json
假设。如果您的 jq 没有 walk/1
,则要么升级到 jq 1.6,要么在调用之前包含其 def(google 搜索词:jq def walk builtin.jq
)。
# input is assumed to be an object
def decrypt($value):
with_entries(if .value|type == "object"
then with_entries(if .value | (type == "object" and has("$crypto"))
then .value = $value else . end)
else . end) ;
walk(if type == "object" then decrypt($cleartext) else . end)
作为已接受答案的补充,如果使用 jq v1.5,请将其用作 decrypt.jq
# input is assumed to be an object
def decrypt($value):
with_entries(if .value|type == "object"
then with_entries(if .value | (type == "object" and has("$crypto"))
then .value = $value else . end)
else . end) ;
# walk was added after the release of jq@1.5
def walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;
walk(if type == "object" then decrypt($cleartext) else . end)