Created
December 19, 2020 06:19
-
-
Save nakabonne/0d07e3dbbe70a5bd1c87029aff97f355 to your computer and use it in GitHub Desktop.
Example of AES-256 GCM encryption with a key derived from password
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"crypto/aes" | |
"crypto/cipher" | |
"crypto/rand" | |
"crypto/sha256" | |
"fmt" | |
"log" | |
"golang.org/x/crypto/pbkdf2" | |
) | |
const ( | |
defaultIterationCount = 100 | |
keyLength = 32 | |
) | |
var hashFunc = sha256.New | |
func main() { | |
var ( | |
password = "pass" | |
salt = []byte("salt") | |
data = []byte("data") | |
) | |
encrypted, err := Encrypt(password, salt, data) | |
if err != nil { | |
log.Fatal(err) | |
} | |
text, err := Decrypt(password, salt, encrypted) | |
if err != nil { | |
log.Fatal(err) | |
} | |
fmt.Println(string(text)) | |
} | |
func Encrypt(password string, salt, data []byte) ([]byte, error) { | |
key := pbkdf2.Key([]byte(password), salt, defaultIterationCount, keyLength, hashFunc) | |
block, err := aes.NewCipher(key) | |
if err != nil { | |
return nil, err | |
} | |
gcm, err := cipher.NewGCM(block) | |
if err != nil { | |
return nil, err | |
} | |
nonce := make([]byte, gcm.NonceSize()) | |
if _, err := rand.Read(nonce); err != nil { | |
return nil, err | |
} | |
encryptedData := gcm.Seal(nonce, nonce, data, nil) | |
return encryptedData, nil | |
} | |
func Decrypt(password string, salt, encryptedData []byte) ([]byte, error) { | |
key := pbkdf2.Key([]byte(password), salt, defaultIterationCount, keyLength, hashFunc) | |
block, err := aes.NewCipher(key) | |
if err != nil { | |
return nil, err | |
} | |
gcm, err := cipher.NewGCM(block) | |
if err != nil { | |
return nil, err | |
} | |
nonceSize := gcm.NonceSize() | |
if len(encryptedData) < nonceSize { | |
return nil, fmt.Errorf("invalid cipher test") | |
} | |
nonce := encryptedData[:nonceSize] | |
ciphertext := encryptedData[nonceSize:] | |
return gcm.Open(nil, nonce, ciphertext, nil) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment