package main import ( "crypto/aes" "crypto/cipher" "crypto/rand" "crypto/sha256" "encoding/hex" "fmt" "strings" "golang.org/x/crypto/pbkdf2" ) func deriveKey(passphrase string, salt []byte) ([]byte, []byte) { if salt == nil { salt = make([]byte, 8) // http://www.ietf.org/rfc/rfc2898.txt // Salt. rand.Read(salt) } return pbkdf2.Key([]byte(passphrase), salt, 1000, 32, sha256.New), salt } func encrypt(passphrase, plaintext string) string { key, salt := deriveKey(passphrase, nil) iv := make([]byte, 12) // http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf // Section 8.2 rand.Read(iv) b, _ := aes.NewCipher(key) aesgcm, _ := cipher.NewGCM(b) data := aesgcm.Seal(nil, iv, []byte(plaintext), nil) return hex.EncodeToString(salt) + "-" + hex.EncodeToString(iv) + "-" + hex.EncodeToString(data) } func decrypt(passphrase, ciphertext string) string { arr := strings.Split(ciphertext, "-") salt, _ := hex.DecodeString(arr[0]) iv, _ := hex.DecodeString(arr[1]) data, _ := hex.DecodeString(arr[2]) key, _ := deriveKey(passphrase, salt) b, _ := aes.NewCipher(key) aesgcm, _ := cipher.NewGCM(b) data, _ = aesgcm.Open(nil, iv, data, nil) return string(data) } func main() { c := encrypt("hello", "world") fmt.Println(c) fmt.Println(decrypt("hello", c)) fmt.Println(decrypt("hello", "c2932347953ad4a4-25f496d260de9c150fc9e4c6-20bc1f8439796cc914eb783b9996a8d9c32d45e2df")) }