package vault import ( "crypto/aes" "crypto/cipher" "crypto/rand" ) var ( _ Encrypter = (*AesGcmEncryption)(nil) _ Decrypter = (*AesGcmEncryption)(nil) ) func NewAesGcmEncryption(deriver KeyDeriver) *AesGcmEncryption { return &AesGcmEncryption{ keyDeriver: deriver, } } type AesGcmEncryption struct { keyDeriver KeyDeriver } func (a AesGcmEncryption) Encrypt(plainText []byte, passphrase string) (cipherText, salt, nonce []byte, err error) { key, salt := a.keyDeriver.DeriveKey(passphrase, nil) block, err := aes.NewCipher(key) if err != nil { return nil, nil, nil, err } aesgcm, err := cipher.NewGCM(block) if err != nil { return nil, nil, nil, err } nonce = make([]byte, aesgcm.NonceSize()) _, _ = rand.Read(nonce) cipherText = aesgcm.Seal(nil, nonce, plainText, nil) return cipherText, salt, nonce, nil } func (a AesGcmEncryption) Decrypt(cipherText []byte, passphrase string, salt, nonce []byte) (plainText []byte, err error) { key, _ := a.keyDeriver.DeriveKey(passphrase, salt) block, err := aes.NewCipher(key) if err != nil { return nil, err } aesgcm, err := cipher.NewGCM(block) if err != nil { return nil, err } return aesgcm.Open(nil, nonce, cipherText, nil) }