github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/talks/2015/json/secret.go (about) 1 // +build OMIT 2 3 package main 4 5 import ( 6 "crypto" 7 "crypto/rand" 8 "crypto/rsa" 9 _ "crypto/sha512" 10 "encoding/base64" 11 "encoding/json" 12 "fmt" 13 "log" 14 ) 15 16 var key *rsa.PrivateKey 17 18 func init() { 19 k, err := rsa.GenerateKey(rand.Reader, 2048) 20 if err != nil { 21 log.Fatalf("generate key: %v", err) 22 } 23 key = k 24 } 25 26 type Person struct { 27 Name string `json:"name"` 28 SSN secret `json:"ssn"` 29 } 30 31 type secret string 32 33 func (s secret) MarshalJSON() ([]byte, error) { 34 m, err := rsa.EncryptOAEP(crypto.SHA512.New(), rand.Reader, key.Public().(*rsa.PublicKey), []byte(s), nil) 35 if err != nil { 36 return nil, err 37 } 38 return json.Marshal(base64.StdEncoding.EncodeToString(m)) 39 } 40 41 func (s *secret) UnmarshalJSON(data []byte) error { 42 var text string 43 if err := json.Unmarshal(data, &text); err != nil { // HL 44 return fmt.Errorf("deocde secret string: %v", err) 45 } 46 cypher, err := base64.StdEncoding.DecodeString(text) // HL 47 if err != nil { 48 return err 49 } 50 raw, err := rsa.DecryptOAEP(crypto.SHA512.New(), rand.Reader, key, cypher, nil) // HL 51 if err == nil { 52 *s = secret(raw) 53 } 54 return err 55 } 56 57 func main() { 58 p := Person{ 59 Name: "Francesc", 60 SSN: "123456789", 61 } 62 63 b, err := json.MarshalIndent(p, "", "\t") 64 if err != nil { 65 log.Fatalf("Encode person: %v", err) 66 } 67 fmt.Printf("%s\n", b) 68 69 var d Person 70 if err := json.Unmarshal(b, &d); err != nil { 71 log.Fatalf("Decode person: %v", err) 72 } 73 fmt.Println(d) 74 }