Struct 在golang结构中转换字符串

Struct 在golang结构中转换字符串,struct,go,aes,Struct,Go,Aes,我有一个AES加密机密的json文件。结构如下: { "username": "asdf123ASLdf3", "password": "elisjdvo4etQW" } 以及保存这些值的结构 type Secrets struct { Username string `json:"username"` Password string `json:"password"` } 将加密的json值加载到结构中很容易,但我真正想要的是一个包含未加密值的结构 因此,对

我有一个AES加密机密的json文件。结构如下:

{
    "username": "asdf123ASLdf3",
    "password": "elisjdvo4etQW"
}
以及保存这些值的结构

type Secrets struct {
    Username string `json:"username"`
    Password string `json:"password"`
}
将加密的json值加载到结构中很容易,但我真正想要的是一个包含未加密值的结构

因此,对于每个值,我希望通过函数运行它:

AES解密(密钥字符串、值字符串)字符串

我很高兴在第一次加载时就完成了这项工作,或者将所有内容移到一个新的结构中

我希望避免重复json键或字段名

最好的方法是什么


(也可以通过其他方式管理Go中的加密机密)

一个选项是定义自定义JSON解组器。另一个是,正如您所提到的,将其复制到另一个结构

  • 实现解组器接口 关键的洞察是知道您可以覆盖
    json.Unmarshal
    通过实施的行为。在我们 在这种情况下,这意味着定义一个函数
    func(ss*Secrets)
    解组JSON(bb[]字节)错误
    ,当 您尝试将任何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)
        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
    struct即可 解密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)
    }
    

    其输出与上述相同:

    {'elisjdvo4etQW' decrypted with key 'my key'
     'asdf123ASLdf3' decrypted with key 'my key'}
    
  • 显然,您将使用不同版本的
    aesdeccrypt
    ,这是我的 只是个傀儡。而且,像往常一样,你应该检查
    在您自己的代码中返回错误。

    我不建议使用自定义JSON解码处理程序,只需创建一个新的结构实例作为
    Secrets{aesdepcrypt(s.Username,key),aesdepcrypt(s.Password,key)}
    ,其中
    s
    是从JSON加载的结构。或者关键的想法是在一个“操作”中完成?我不在乎在一个操作中完成,但我希望这样做,而不必重复json键或字段名。如果向下投票和标记关闭都有原因,那就太好了。可能会帮助社区改善。这就是说,令人惊讶的是,我们采取了这两种行动,因为这似乎是一个涉及编程的合理问题,其他人可能会提出并发现这一问题很有用。这似乎很方便,但我认为您的示例中的主要挑战是如何为对
    json.Unmarshal()
    的每次调用提供自定义密钥。这与通常的解组方案有所不同,后者的输出完全依赖于JSON数据输入。@tomasz:很好。我完全同意这是一个问题。我在说明<代码> Unmarshal <代码>代码,并考虑对密钥的处理和与问题正交的实际解密。我认为用任何“真正的”代码都不难处理。当然,这取决于需求。我喜欢第二种方法,因为它不再需要再次键入json键名。谢谢@Ezra很抱歉,我“不接受”这个答案,因为我需要更多地思考它——我认为不必重复json键或字段名很重要。随着机密数量的增加,出现了大量重复的名称,出现错误的可能性也越来越大。当然可以讨论。一般来说,我很好奇在围棋中处理加密秘密的最佳方法是什么。我不确定我是否理解。如果您像(1)中那样实现
    Unmarshaler
    ,那么任何额外的机密所需的唯一代码就是(最多)
    json.Unmarshal(jj,&ss)
    。对于每一个额外的项目,引用它们的次数不可能少于零次,我不确定你在寻找什么。祝你好运找到它!干杯