在 golang 结构中转换字符串
transforming strings in a golang struct
我有一个 json AES 加密机密文件。结构是:
{
"username": "asdf123ASLdf3",
"password": "elisjdvo4etQW"
}
以及保存这些值的结构
type Secrets struct {
Username string `json:"username"`
Password string `json:"password"`
}
将加密的 json 值加载到结构中很容易,但我真正想要的是具有未加密值的结构。
所以,对于每个值,我想 运行 它通过一个函数:
aesDecrypt(key string, value string) string
我很高兴在第一次加载时完成此操作,或者将所有内容移至新结构中。
我想避免重复 json 键或字段名称。
最好的方法是什么?
(也开放其他方式来管理 Go 中的加密秘密)
一个选项是定义自定义 JSON Unmarshaler。另一个是,正如你提到的,将它复制到另一个结构。
实现 Unmarshaler 接口
关键的见解是知道您可以覆盖 json.Unmarshal
的
通过实施 the Unmarshaler interface 的行为。在我们的
情况下,这意味着定义一个函数 func (ss *Secrets)
UnmarshalJSON(bb []byte) error
,它将在以下情况下进行 AES 解密
您尝试将任何 JSON 解组为 Secrets
.
package main
import "fmt"
import "encoding/json"
type Secrets struct {
Username string `json:"username"`
Password string `json:"password"`
}
func main() {
jj := []byte(`{
"username": "asdf123ASLdf3",
"password": "elisjdvo4etQW"
}`)
var ss Secrets
json.Unmarshal(jj, &ss)
fmt.Println(ss)
}
func aesDecrypt(key, value string) string {
return fmt.Sprintf("'%s' decrypted with key '%s'", value, key)
}
func (ss *Secrets) UnmarshalJSON(bb []byte) error {
var objmap map[string]*string
err := json.Unmarshal(bb, &objmap)
ss.Username = aesDecrypt("my key", *objmap["password"])
ss.Password = aesDecrypt("my key", *objmap["username"])
return err
}
这会输出一个 Secrets
结构:
{'elisjdvo4etQW' decrypted with key 'my key'
'asdf123ASLdf3' decrypted with key 'my key'}
复制到另一个结构
您可以在每次需要时简单地创建一个新的 Secrets
结构
解密JSON。如果你经常这样做,这可能会很乏味,或者如果你
不需要中间状态。
package main
import "fmt"
import "encoding/json"
type Secrets struct {
Username string `json:"username"`
Password string `json:"password"`
}
func main() {
jj := []byte(`{
"username": "asdf123ASLdf3",
"password": "elisjdvo4etQW"
}`)
var ss Secrets
json.Unmarshal(jj, &ss)
decoded := Secrets{
aesDecrypt(ss.Username, "my key"),
aesDecrypt(ss.Password, "my key")}
fmt.Println(decoded)
}
func aesDecrypt(key, value string) string {
return fmt.Sprintf("'%s' decrypted with key '%s'", value, key)
}
Check it out at Go Playground.
这与上面的输出相同:
{'elisjdvo4etQW' decrypted with key 'my key'
'asdf123ASLdf3' decrypted with key 'my key'}
显然,您会使用我的 aesDecrypt
的不同版本
只是一个假人。而且,一如既往,你实际上应该检查
在您自己的代码中返回错误。
我有一个 json AES 加密机密文件。结构是:
{
"username": "asdf123ASLdf3",
"password": "elisjdvo4etQW"
}
以及保存这些值的结构
type Secrets struct {
Username string `json:"username"`
Password string `json:"password"`
}
将加密的 json 值加载到结构中很容易,但我真正想要的是具有未加密值的结构。
所以,对于每个值,我想 运行 它通过一个函数:
aesDecrypt(key string, value string) string
我很高兴在第一次加载时完成此操作,或者将所有内容移至新结构中。
我想避免重复 json 键或字段名称。
最好的方法是什么?
(也开放其他方式来管理 Go 中的加密秘密)
一个选项是定义自定义 JSON Unmarshaler。另一个是,正如你提到的,将它复制到另一个结构。
实现 Unmarshaler 接口
关键的见解是知道您可以覆盖
json.Unmarshal
的 通过实施 the Unmarshaler interface 的行为。在我们的 情况下,这意味着定义一个函数func (ss *Secrets) UnmarshalJSON(bb []byte) error
,它将在以下情况下进行 AES 解密 您尝试将任何 JSON 解组为Secrets
.package main import "fmt" import "encoding/json" type Secrets struct { Username string `json:"username"` Password string `json:"password"` } func main() { jj := []byte(`{ "username": "asdf123ASLdf3", "password": "elisjdvo4etQW" }`) var ss Secrets json.Unmarshal(jj, &ss) fmt.Println(ss) } func aesDecrypt(key, value string) string { return fmt.Sprintf("'%s' decrypted with key '%s'", value, key) } func (ss *Secrets) UnmarshalJSON(bb []byte) error { var objmap map[string]*string err := json.Unmarshal(bb, &objmap) ss.Username = aesDecrypt("my key", *objmap["password"]) ss.Password = aesDecrypt("my key", *objmap["username"]) return err }
这会输出一个
Secrets
结构:{'elisjdvo4etQW' decrypted with key 'my key' 'asdf123ASLdf3' decrypted with key 'my key'}
复制到另一个结构
您可以在每次需要时简单地创建一个新的
Secrets
结构 解密JSON。如果你经常这样做,这可能会很乏味,或者如果你 不需要中间状态。package main import "fmt" import "encoding/json" type Secrets struct { Username string `json:"username"` Password string `json:"password"` } func main() { jj := []byte(`{ "username": "asdf123ASLdf3", "password": "elisjdvo4etQW" }`) var ss Secrets json.Unmarshal(jj, &ss) decoded := Secrets{ aesDecrypt(ss.Username, "my key"), aesDecrypt(ss.Password, "my key")} fmt.Println(decoded) } func aesDecrypt(key, value string) string { return fmt.Sprintf("'%s' decrypted with key '%s'", value, key) }
Check it out at Go Playground.
这与上面的输出相同:
{'elisjdvo4etQW' decrypted with key 'my key' 'asdf123ASLdf3' decrypted with key 'my key'}
显然,您会使用我的 aesDecrypt
的不同版本
只是一个假人。而且,一如既往,你实际上应该检查
在您自己的代码中返回错误。