转换golang结构中的字符串

时间:2015-06-18 15:19:23

标签: struct go aes

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

{
    "username": "asdf123ASLdf3",
    "password": "elisjdvo4etQW"
}

用于保存这些值的结构

type Secrets struct {
    Username string `json:"username"`
    Password string `json:"password"`
}

将加密的json值加载到结构中很容易,但我真正想要的是具有未加密值的结构。

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

aesDecrypt(key string, value string) string

我很高兴在第一次加载时完成此操作,或将所有内容移动到新结构中。

我想避免重复json键或字段名称。

最好的方法是什么?

(也开放其他方式来管理Go中的加密机密)

1 个答案:

答案 0 :(得分:2)

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

  1. 实施Unmarshaler接口

    关键洞察力是知道您可以覆盖json.Unmarshal 通过实施the Unmarshaler interface的行为。在我们的 case,这意味着定义一个函数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'}
    

    See it in action at the Go Playground.

  2. 复制到另一个结构

    您可以在每次需要时简单地创建一个新的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'}
    
  3. 显然,你会使用不同版本的aesDecrypt,我的 只是一个假人。并且,一如既往,你应该实际检查 在您自己的代码中返回错误。