Sling Academy
Home/Golang/Encrypting Data with ChaCha20-Poly1305 in Go

Encrypting Data with ChaCha20-Poly1305 in Go

Last updated: November 27, 2024

ChaCha20-Poly1305 is an authenticated encryption algorithm that combines the ChaCha20 stream cipher with the Poly1305 message authentication code. It provides both confidentiality and data integrity, making it suitable for secure communication. In this article, we'll explore how to implement ChaCha20-Poly1305 encryption and decryption in Go.

Setting Up

Let's create a new Go module for our application:

mkdir chacha20poly1305-example
cd chacha20poly1305-example
go mod init chacha20poly1305-example

Encrypting Data

First, let's write a function to encrypt data using ChaCha20-Poly1305. We'll use Go's built-in golang.org/x/crypto/chacha20poly1305 package, so make sure to get it using:

go get golang.org/x/crypto/chacha20poly1305

Here is a function to encrypt a given plaintext using a 32-byte key:

package main

import (
    "crypto/rand"
    "fmt"
    "golang.org/x/crypto/chacha20poly1305"
    "log"
)

func encrypt(plaintext, key []byte) (nonce, ciphertext []byte, err error) {
    aead, err := chacha20poly1305.New(key)
    if err != nil {
        return nil, nil, err
    }

    nonce = make([]byte, chacha20poly1305.NonceSize)
    if _, err := rand.Read(nonce); err != nil {
        return nil, nil, err
    }

    ciphertext = aead.Seal(nil, nonce, plaintext, nil)
    return nonce, ciphertext, nil
}

This function generates a secure nonce and uses it along with your key to produce the ciphertext.

Decrypting Data

Let us now create a function to decrypt the data using the same nonce and key:

func decrypt(nonce, ciphertext, key []byte) (plaintext []byte, err error) {
    aead, err := chacha20poly1305.New(key)
    if err != nil {
        return nil, err
    }

    plaintext, err = aead.Open(nil, nonce, ciphertext, nil)
    return plaintext, err
}

This decryption function will validate the authenticity of the message using the Poly1305 tag and, if successful, decrypt the ciphertext back to the plaintext.

Putting It All Together

We can now write a main function to demonstrate encrypting and decrypting a message:

func main() {
    key := []byte("thisis32bytekeyforchachapoly130512")
    plaintext := []byte("Hello, World!")

    nonce, ciphertext, err := encrypt(plaintext, key)
    if err != nil {
        log.Fatalf("Error encrypting: %v", err)
    }

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

    decryptedText, err := decrypt(nonce, ciphertext, key)
    if err != nil {
        log.Fatalf("Error decrypting: %v", err)
    }

    fmt.Printf("Decrypted Text: %s\n", decryptedText)
}

Run your application with go run . and observe the encryption and decryption process. You should see that the decrypted text matches your original plaintext message.

Conclusion

In this guide, we explored how to use the ChaCha20-Poly1305 algorithm for secure encryption and decryption in Go. This algorithm not only ensures the confidentiality of the data but also provides integrity and authenticity, making it highly effective for secure communications.

Next Article: Key Management Best Practices in Go Applications

Previous Article: Creating and Verifying Digital Signatures 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