You can use example below for data encryption and decryption purposes in Golang. It uses a static secret key and is ideal if the encryption and decryption take place in same machine. You can use the encrypted data in URL.


Example


package main

import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"fmt"
"io"
)

func main() {
// You can generate this only once and use as an environment variable.
secret, err := secret()
if err != nil {
panic(fmt.Sprintf("unable to create secret key: %v", err))
}

message := "I am a very secret message"
fmt.Println("Message:", message)

encrypted, err := encrypt(message, secret)
if err != nil {
panic(fmt.Sprintf("unable to encrypt the data: %v", err))
}
fmt.Println("Encrypted:", encrypted)

decrypted, err := decrypt(encrypted, secret)
if err != nil {
panic(fmt.Sprintf("unable to decrypt the data: %v", err))
}
fmt.Println("Decrypted:", decrypted)
}

// secret returns a 32 bytes AES key.
func secret() ([]byte, error) {
key := make([]byte, 16)

if _, err := rand.Read(key); err != nil {
return nil, err
}

return key, nil
}

// encrypt encrypts plain string with a secret key and returns encrypt string.
func encrypt(plainData string, secret []byte) (string, error) {
cipherBlock, err := aes.NewCipher(secret)
if err != nil {
return "", err
}

aead, err := cipher.NewGCM(cipherBlock)
if err != nil {
return "", err
}

nonce := make([]byte, aead.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
return "", err
}

return base64.URLEncoding.EncodeToString(aead.Seal(nonce, nonce, []byte(plainData), nil)), nil
}

// decrypt decrypts encrypt string with a secret key and returns plain string.
func decrypt(encodedData string, secret []byte) (string, error) {
encryptData, err := base64.URLEncoding.DecodeString(encodedData)
if err != nil {
return "", err
}

cipherBlock, err := aes.NewCipher(secret)
if err != nil {
return "", err
}

aead, err := cipher.NewGCM(cipherBlock)
if err != nil {
return "", err
}

nonceSize := aead.NonceSize()
if len(encryptData) < nonceSize {
return "", err
}

nonce, cipherText := encryptData[:nonceSize], encryptData[nonceSize:]
plainData, err := aead.Open(nil, nonce, cipherText, nil)
if err != nil {
return "", err
}

return string(plainData), nil
}

Example


$ go run -race main.go 
Message: I am a very secret message
Encrypted: tW-khZy3YYpYytPjfffrwHXaaNqMZxugqeBx5vkgc75Nd8HUky8duwit8CiGOUecN5ZxxRox
Decrypted: I am a very secret message

$ go run -race main.go
Message: I am a very secret message
Encrypted: Xbvm0z0wC1eHJqaWZn03vDYUdO4NgtWvXEN_aqjQaKw6J_oKXlOVXOyRp8N8s0qtEHUm93Ny
Decrypted: I am a very secret message

$ go run -race main.go
Message: I am a very secret message
Encrypted: 13hKVuxfVVcRMD3-aW5eiXRGgWChIws56px7pc41yTYkdoJ-obIaBu3-p9SLIIvMY_4aeP9y
Decrypted: I am a very secret message

$ go run -race main.go
Message: I am a very secret message
Encrypted: 8XCqFxJkZKGKC1rYmxU_1-HvYVWwJvN3WmkRSZBHFSKSEaJBmvDuP0HHAwjjE_hvWxgT2jLY
Decrypted: I am a very secret message

$ go run -race main.go
Message: I am a very secret message
Encrypted: 3o8p-xTEcDtSvz6PRdIbK9TRqBmrPohxh6XM33hlMnsZCvkZDbp5Eo4_mqAELZof91sFyvdY
Decrypted: I am a very secret message