Go で暗号化、複合化を良い感じにやりたい。
良い感じとはプロダクションはAWS KMSを使用しつつローカルはKMSに依存しないものを使いたい。という感じ。
自分で作っても良いかなと思ったけど既存でないかと探したらThe Go Cloud Development Kitというものを見つけた。
gocloud.dev
これは Google で提供されているパッケージ群で、今回の暗号化・複合化のパッケージ以外にもPubSubやらMySQLのクライアントとか便利そうなものが色々提供されているっぽい。
ドキュメントをみる感じ下記のようにパッケージを import してあげて後はローカルの時は base64key://
、AWS KMSを使いたい時は awskms://{AWS KMS ID}
を渡すと良い感じにやってくれる。
import ( "gocloud.dev/secrets" _ "gocloud.dev/secrets/awskms" _ "gocloud.dev/secrets/localsecrets" )
試してみる
まずは暗号化・複合化してくれる package を作ります。
package crypter import ( "context" "gocloud.dev/secrets" _ "gocloud.dev/secrets/awskms" _ "gocloud.dev/secrets/localsecrets" ) type Crypter interface { Encrypt(context.Context, []byte) ([]byte, error) Decrypt(context.Context, []byte) ([]byte, error) } type crypter struct { keeper *secrets.Keeper } func NewCrypter(ctx context.Context, url string) (Crypter, error) { keeper, err := secrets.OpenKeeper(ctx, url) if err != nil { return nil, err } return &crypter{ keeper: keeper, }, nil } func (c *crypter) Encrypt(ctx context.Context, pt []byte) ([]byte, error) { cipherText, err := c.keeper.Encrypt(ctx, pt) if err != nil { return nil, err } return cipherText, nil } func (c *crypter) Decrypt(ctx context.Context, ct []byte) ([]byte, error) { plainText, err := c.keeper.Decrypt(ctx, ct) if err != nil { return nil, err } return plainText, nil }
後はこのパッケージを使うように main パッケージを定義する
package main import ( "context" "flag" "log" "github.com/hatappi/enc-dec/crypter" ) func main() { var ( text string url string ) flag.StringVar(&text, "text", "", "text") flag.StringVar(&url, "url", "", "url") flag.Parse() ctx := context.Background() crypter, err := crypter.NewCrypter(ctx, url) if err != nil { log.Fatal(err) } ct, err := crypter.Encrypt(ctx, []byte(text)) if err != nil { log.Fatal(err) } pt, err := crypter.Decrypt(ctx, ct) if err != nil { log.Fatal(err) } log.Printf("plainText is %s\n", pt) }
実行
後は go build -o enc-dec
でビルドして実行する。
$ ./enc-dec --text test --url base64key:// 2020/03/16 00:00:00 plainText is test $ ./enc-dec --text test --url "awskms://xxxxxx-yyyy-xxxxx-yyyyy" 2020/03/16 00:00:00 plainText is test