Secure Data Encryption and Decryption in Go Using AES
In this post, we’ll demonstrate how to implement secure data encryption and decryption using AES (Advanced Encryption Standard) in Go. AES is a widely used symmetric encryption algorithm that ensures data confidentiality. We will use AES in CFB (Cipher Feedback) mode for this implementation.
Introduction to AES Encryption
AES is a symmetric key encryption algorithm that encrypts data using the same key for both encryption and decryption. In CFB mode, AES can be used to encrypt data of arbitrary length, making it suitable for stream encryption.
Implementing AES Encryption and Decryption in Go
Here’s a Go program that demonstrates how to encrypt and decrypt data using AES with CFB mode:
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"fmt"
"io"
)
// Function to generate a random 32-byte key.
func generateRandomKey() ([]byte, error) {
key := make([]byte, 32)
_, err := rand.Read(key)
if err != nil {
return nil, err
}
return key, nil
}
// Function to encrypt plaintext using the given key.
func encrypt(plaintext []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
return ciphertext, nil
}
// Function to decrypt ciphertext using the given key.
func decrypt(ciphertext []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(ciphertext) < aes.BlockSize {
return nil, fmt.Errorf("ciphertext too short")
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(ciphertext, ciphertext)
return ciphertext, nil
}
func main() {
// Example usage
plaintext := []byte("This is the plaintext to be encrypted!89")
key, err := generateRandomKey()
if err != nil {
fmt.Println("Error generating key:", err)
return
}
ciphertext, err := encrypt(plaintext, key)
if err != nil {
fmt.Println("Error encrypting:", err)
return
}
fmt.Println("Ciphertext:", base64.StdEncoding.EncodeToString(ciphertext))
decryptedText, err := decrypt(ciphertext, key)
if err != nil {
fmt.Println("Error decrypting:", err)
return
}
fmt.Println("Decrypted text:", string(decryptedText))
}
Explanation of the Code
-
Generating a Random Key:
- The
generateRandomKey
function creates a random 32-byte key usingcrypto/rand
. This key is used for both encryption and decryption.
- The
-
Encrypting Data:
- The
encrypt
function initializes an AES cipher in CFB mode. It generates a random initialization vector (IV) and uses it along with the key to encrypt the plaintext. The ciphertext includes both the IV and the encrypted data.
- The
-
Decrypting Data:
- The
decrypt
function extracts the IV from the beginning of the ciphertext, then uses the key and the IV to decrypt the rest of the ciphertext.
- The
-
Main Function:
- Demonstrates how to use the
generateRandomKey
,encrypt
, anddecrypt
functions. It prints the ciphertext encoded in base64 and the decrypted text.
- Demonstrates how to use the
Conclusion
This Go implementation of AES encryption and decryption provides a straightforward method for securing data. By using AES in CFB mode, you can ensure that your data remains confidential and protected from unauthorized access. The example code generates a random key, encrypts plaintext, and then decrypts the ciphertext to verify the process.