Sling Academy
Home/Golang/Understanding Symmetric Encryption with AES in Go

Understanding Symmetric Encryption with AES in Go

Last updated: November 27, 2024

Symmetric encryption is a type of encryption where the same key is used for both encryption and decryption of the data. One of the most popular symmetric key algorithms is the Advanced Encryption Standard (AES). In this article, we will explore how to implement AES encryption in Go, a statically typed, compiled programming language known for its efficiency and concurrency support.

Introduction to AES

AES is a symmetric key encryption standard adopted by the US government and widely used across the globe. It is secure, fast, and flexible, making it ideal for various applications. AES typically supports key sizes of 128, 192, and 256 bits. In this guide, we'll work with AES-256.

Example: Implementing AES Encryption in Go

Let's start by writing a program to encrypt a message using AES:


package main

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

// encryptAES encrypts plain text string into cipher text string
func encryptAES(plainText string, key string) (string, error) {
	text := []byte(plainText)
	block, err := aes.NewCipher([]byte(key))
	if err != nil {
		return "", err
	}

	ciphertext := make([]byte, aes.BlockSize+len(text))
	iv := ciphertext[:aes.BlockSize]
	randomBytes := make([]byte, len(iv))
	if _, err := io.ReadFull(rand.Reader, randomBytes); err != nil {
		return "", err
	}
	copy(iv, randomBytes)

	stream := cipher.NewCFBEncrypter(block, iv)
	stream.XORKeyStream(ciphertext[aes.BlockSize:], text)

	// Convert encrypted data to hexadecimal format
	return fmt.Sprintf("%x", ciphertext), nil
}

func main() {
	key := "thisis32bitlongpassphraseimusing"
	plainText := "Hello, World!"
	cipherText, err := encryptAES(plainText, key)
	if err != nil {
		fmt.Println("Error encrypting:", err)
	}
	fmt.Printf("Encrypted message: %s\n", cipherText)
}

In this example, we define a key and a plain text message, use the encryptAES function to encrypt the message, and then print the encrypted message. Note that encryptAES requires a key of appropriate length (32 bytes for AES-256).

Decrypting the Message

Decrypting an AES message is very similar to encrypting it, but reverses some operations:


// decryptAES decrypts an encrypted text string back into plain text
func decryptAES(encryptedText string, key string) (string, error) {
	ciphertext, err := hex.DecodeString(encryptedText)
	if err != nil {
		return "", err
	}

	block, err := aes.NewCipher([]byte(key))
	if err != nil {
		return "", err
	}

	if len(ciphertext) < aes.BlockSize {
		return "", fmt.Errorf("ciphertext too short")
	}

	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	stream := cipher.NewCFBDecrypter(block, iv)
	stream.XORKeyStream(ciphertext, ciphertext)

	return string(ciphertext), nil
}

// Using the decryptAES function
func main() {
	key := "thisis32bitlongpassphraseimusing"
	encryptedText := "9a256aed9c9b1f6134bf2cafeb8cf84019125c2696abbuf2af304f"
	decryptedText, err := decryptAES(encryptedText, key)
	if err != nil {
		fmt.Println("Error decrypting:", err)
	}
	fmt.Printf("Decrypted message: %s\n", decryptedText)
}

This code reads the encoded message, derives the initialization vector (IV), and decrypts the ciphertext back into plaintext using the same key.

Conclusion

AES encryption in Go is straightforward thanks to the robust support of Go libraries. As shown, encrypting and decrypting messages with symmetric algorithms can be efficiently done with a proper understanding of Go’s cryptography packages. Remember to securely handle encryption keys and initialization vectors in your applications.

Next Article: Implementing RSA Encryption for Secure Communication in Go

Previous Article: Hashing Passwords Securely with `bcrypt` in Go

Series: Cryptography and Security in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant