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  }