duanbo6482 2015-06-18 15:19
浏览 171
已采纳

在golang结构中转换字符串

I've got a json file of AES encrypted secrets. The structure is:

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

And a struct to hold these values

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

It's easy to load the encrypted json values into the struct, but what I really want is a struct with the unencrypted values.

So, for each value, I'd like to run it though a function:

aesDecrypt(key string, value string) string

I'm happy to have this done on the first load, or to move everything over into a new struct.

I would like to avoid repeating the json keys or the field names.

What's the best way to do this?

(Also open to other ways to manage encrypted secrets in Go)

  • 写回答

1条回答 默认 最新

  • dpvomqeu396484 2015-06-18 15:59
    关注

    One option is to define a custom JSON Unmarshaler. Another is, as you mention, copy it to another struct.

    1. Implementing the Unmarshaler interface

      The key insight is knowing that you can override json.Unmarshal's behaviour by implementing the Unmarshaler interface. In our case, that means defining a function func (ss *Secrets) UnmarshalJSON(bb []byte) error that will do the AES Decryption when you try to unmarshal any JSON to a 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
      }
      

      This outputs a Secrets struct:

      {'elisjdvo4etQW' decrypted with key 'my key'
       'asdf123ASLdf3' decrypted with key 'my key'}
      

      See it in action at the Go Playground.

    2. Copying to another struct

      You could simply make a new Secrets struct every time you need to decrypt the JSON. This could be tedious if you do it alot, or if you have no need for the intermediate state.

      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.

      This has the same output as above:

      {'elisjdvo4etQW' decrypted with key 'my key'
       'asdf123ASLdf3' decrypted with key 'my key'}
      

    Obviously, you would use a different version of aesDecrypt, mine's just a dummy. And, as always, you should actually be checking the returned errors in your own code.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 WPF动态创建页面内容
  • ¥15 如何对TBSS的结果进行统计学的分析已完成置换检验,如何在最终的TBSS输出结果提取除具体值及如何做进一步相关性分析
  • ¥15 SQL数据库操作问题
  • ¥100 关于lm339比较电路出现的问题
  • ¥15 Matlab安装yalmip和cplex功能安装失败
  • ¥15 加装宝马安卓中控改变开机画面
  • ¥15 STK安装问题问问大家,这种情况应该怎么办
  • ¥15 关于罗技鼠标宏lua文件的问题
  • ¥15 halcon ocr mlp 识别问题
  • ¥15 已知曲线满足正余弦函数,根据其峰值,还原出整条曲线