Sling Academy
Home/Golang/Using `crypto/cipher` for Advanced Encryption Techniques in Go

Using `crypto/cipher` for Advanced Encryption Techniques in Go

Last updated: November 27, 2024

Using the crypto/cipher package in Go allows developers to implement a variety of secure encryption techniques. This guide will walk through some common uses of this package to encrypt and decrypt data securely.

Getting Started with crypto/cipher

First, you'll need to import the relevant packages in your Go project. Here's a basic setup:

package main

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

Encrypting Data with AES

AES (Advanced Encryption Standard) is a widely used encryption algorithm. Here's how you might implement basic AES encryption using crypto/cipher:

func encrypt(secret []byte, plaintext []byte) ([]byte, error) {
    block, err := aes.NewCipher(secret)
    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
}

Note that secret should be a byte slice with a length of 16, 24, or 32, corresponding to AES-128, AES-192, or AES-256 respectively.

Decrypting Data

Decryption is the reverse process, using the cipher stream:

func decrypt(secret []byte, ciphertext []byte) ([]byte, error) {
    block, err := aes.NewCipher(secret)
    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
}

Example Usage

Let's look at a simple example to encrypt and decrypt a message:

func main() {
    secret := []byte("myverystrongpasswordo32bitlength")
    message := []byte("Secret message!")

    fmt.Printf("Original: %s\n", string(message))

    encrypted, err := encrypt(secret, message)
    if err != nil {
        fmt.Println("Error encrypting:", err)
        return
    }
    fmt.Printf("Encrypted: %x\n", encrypted)

    decrypted, err := decrypt(secret, encrypted)
    if err != nil {
        fmt.Println("Error decrypting:", err)
        return
    }
    fmt.Printf("Decrypted: %s\n", string(decrypted))
}

This example should provide a basic understanding of using crypto/cipher with AES encryption and decryption in Go. These examples use AES in CFB mode. Always ensure your application uses the correct encryption method suitable for your specific needs, and never reuse IVs with the same key.

Next Article: What Is Elliptic Curve Cryptography (ECC) and How to Use It in Go

Previous Article: Building a Secure Password Vault with 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