|
@@ -0,0 +1,82 @@
|
|
|
+package util
|
|
|
+
|
|
|
+import (
|
|
|
+ "crypto/aes"
|
|
|
+ "crypto/cipher"
|
|
|
+ "crypto/rand"
|
|
|
+ "encoding/hex"
|
|
|
+ "fmt"
|
|
|
+ "io"
|
|
|
+)
|
|
|
+
|
|
|
+func GenerateKeyAndNonce() (string, string, error) {
|
|
|
+ // The key argument should be the AES key, either 16 or 32 bytes
|
|
|
+ // to select AES-128 or AES-256.
|
|
|
+ key := make([]byte, 32)
|
|
|
+ if _, err := io.ReadFull(rand.Reader, key); err != nil {
|
|
|
+ return "", "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ // Never use more than 2^32 random nonces with a given key because of
|
|
|
+ // the risk of a repeat.
|
|
|
+ nonce := make([]byte, 12)
|
|
|
+ if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
|
|
+ return "", "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ return fmt.Sprintf("%x", key), fmt.Sprintf("%x", nonce), nil
|
|
|
+}
|
|
|
+
|
|
|
+func ValidateKeyAndNonce(keyHexStr, nonceHexStr string) ([]byte, []byte, error) {
|
|
|
+ key, err := hex.DecodeString(keyHexStr)
|
|
|
+ if err != nil {
|
|
|
+ return nil, nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ nonce, err := hex.DecodeString(nonceHexStr)
|
|
|
+ if err != nil {
|
|
|
+ return nil, nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return key, nonce, nil
|
|
|
+}
|
|
|
+
|
|
|
+func Encrypt(key []byte, nonce []byte, plainText string) (string, error) {
|
|
|
+ block, err := aes.NewCipher(key)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ aesgcm, err := cipher.NewGCM(block)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ cipherText := aesgcm.Seal(nil, nonce, []byte(plainText), nil)
|
|
|
+
|
|
|
+ return fmt.Sprintf("%x", cipherText), nil
|
|
|
+}
|
|
|
+
|
|
|
+func Decrypt(key []byte, nonce []byte, cipherHexStr string) (string, error) {
|
|
|
+ block, err := aes.NewCipher(key)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ aesgcm, err := cipher.NewGCM(block)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ cipherText, err := hex.DecodeString(cipherHexStr)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ plainText, err := aesgcm.Open(nil, nonce, []byte(cipherText), nil)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ return string(plainText), nil
|
|
|
+}
|