Sling Academy
Home/Golang/Protecting Sensitive Data with GCM Mode Encryption in Go

Protecting Sensitive Data with GCM Mode Encryption in Go

Last updated: November 27, 2024

When dealing with sensitive information, ensuring its confidentiality and integrity during transmission and storage is crucial. Galois/Counter Mode (GCM) provides both encryption and message authentication, making it a popular choice for protecting sensitive data. This article will guide you through implementing GCM mode encryption in the Go programming language.

What is GCM Mode?

GCM (Galois/Counter Mode) is a mode of operation for symmetric key cryptographic block ciphers. It is designed to provide both data authenticity through a MAC (Message Authentication Code) and data confidentiality. By combining these two features, GCM helps safeguard against unauthorized data tampering and access.

Prerequisites

To follow along with this guide, ensure that you have the following:

  • Go installed on your machine.
  • A basic understanding of Go programming language.

Encrypting Data Using GCM in Go

Let’s look at an example of how to encrypt data using the GCM mode of encryption in Go:


package main

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

func main() {
    key := []byte("a very secret key!!") // 16, 24 or 32 bytes
    plaintext := []byte("Sensitive data")

    // Generates a new AES cipher using the secret key.
    block, err := aes.NewCipher(key)
    if err != nil {
        panic(err.Error())
    }

    // Wrap the cipher block into a Galois Counter Mode.
    nonce := make([]byte, 12) // GCM standard nonce size is 12 bytes
    if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
        panic(err.Error())
    }

    aesGCM, err := cipher.NewGCM(block)
    if err != nil {
        panic(err.Error())
    }

    // Encrypt and authenticate data.
    ciphertext := aesGCM.Seal(nil, nonce, plaintext, nil)

    fmt.Printf("Nonce: %x\n", nonce)
    fmt.Printf("Ciphertext: %x\n", ciphertext)
}

In this code snippet:

  • We start by defining a key and plaintext. The key length should be 16, 24, or 32 bytes for AES encryption.
  • We create a new AES cipher block with the provided key.
  • We generate a random nonce of 12 bytes, which is the standard size for GCM.
  • We initialize GCM using the cipher block.
  • Finally, we use the GCM to encrypt the plaintext, producing ciphertext with an embedded authentication tag.

Decrypting Data with GCM in Go

Decrypting data encrypted with GCM mode in Go involves verifying the message authentication tag before decryption:


func decrypt(ciphertext, key, nonce []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }

    aesGCM, err := cipher.NewGCM(block)
    if err != nil {
        return nil, err
    }

    // Decrypt and authenticate data.
    plaintext, err := aesGCM.Open(nil, nonce, ciphertext, nil)
    if err != nil {
        return nil, err
    }

    return plaintext, nil
}

func main() {
    key := []byte("a very secret key!!")
    nonce := []byte{...} // nonce used during encryption
    ciphertext := []byte{...} // ciphertext received

    plaintext, err := decrypt(ciphertext, key, nonce)
    if err != nil {
        fmt.Println("Failed to decrypt:", err)
    } else {
        fmt.Printf("Plaintext: %s\n", plaintext)
    }
}

By using the function decrypt:

  • We set up the cipher block and GCM instance as before.
  • We decrypt the ciphertext while also verifying its integrity.
  • The plaintext is only returned if the authentication is successful.

Security Considerations

When using GCM mode encryption, it's essential to take into account:

  • Always use a unique nonce for every encryption operation with the same key to maintain data confidentiality.
  • Keep your encryption keys secure, as anyone with the key can read the data.
  • Verify that the libraries you utilize are up-to-date to avoid potential vulnerabilities.

By following these best practices, you can ensure that your data remains protected against unauthorized access or alterations.

Next Article: Introduction to Zero-Knowledge Proofs in Go

Previous Article: How to Verify SSL/TLS Certificates 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