codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🐹

Go (Golang)

58 / 72 topics
55Security Best Practices for Go Apps56Input Validation57Secure Coding Practices58Encryption and Decryption in Go59Authentication and Authorization
Tutorials/Go (Golang)/Encryption and Decryption in Go
🐹Go (Golang)

Encryption and Decryption in Go

Updated 2026-04-20
2 min read

Encryption and Decryption in Go

Introduction

Encryption is a critical aspect of software security, ensuring that sensitive data remains confidential. In this tutorial, we will explore how to implement encryption and decryption in Go using the crypto package, which provides cryptographic primitives for secure communication.

Prerequisites

Before diving into the implementation details, ensure you have the following:

  • Basic knowledge of Go programming.
  • A working Go environment set up on your machine.

Overview

In this tutorial, we will cover:

  1. Symmetric Encryption: Using AES (Advanced Encryption Standard).
  2. Asymmetric Encryption: Using RSA.
  3. Hashing and Salting Passwords.
  4. Best Practices for Security.

Symmetric Encryption with AES

Symmetric encryption uses the same key for both encryption and decryption. AES is a widely used symmetric encryption algorithm.

Step 1: Import Required Packages

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

Step 2: Generate a Key

AES requires a key of either 16, 24, or 32 bytes. For this example, we'll use a 32-byte key.

func generateKey() ([]byte, error) {
    key := make([]byte, 32)
    if _, err := io.ReadFull(rand.Reader, key); err != nil {
        return nil, err
    }
    return key, nil
}

Step 3: Encrypt Data

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

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

    nonce := make([]byte, gcm.NonceSize())
    if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
        return "", err
    }

    ciphertext := gcm.Seal(nonce, nonce, data, nil)
    return base64.URLEncoding.EncodeToString(ciphertext), nil
}

Step 4: Decrypt Data

func decrypt(token string, key []byte) ([]byte, error) {
    ciphertext, err := base64.URLEncoding.DecodeString(token)
    if err != nil {
        return nil, err
    }

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

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

    nonceSize := gcm.NonceSize()
    if len(ciphertext) < nonceSize {
        return nil, fmt.Errorf("ciphertext too short")
    }

    nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
    plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
    if err != nil {
        return nil, err
    }

    return plaintext, nil
}

Step 5: Example Usage

func main() {
    key, _ := generateKey()
    data := []byte("Hello, World!")

    encryptedData, _ := encrypt(data, key)
    fmt.Println("Encrypted:", encryptedData)

    decryptedData, _ := decrypt(encryptedData, key)
    fmt.Println("Decrypted:", string(decryptedData))
}

Asymmetric Encryption with RSA

Asymmetric encryption uses a pair of keys: a public key for encryption and a private key for decryption. RSA is commonly used for secure data transmission.

Step 1: Generate RSA Keys

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "fmt"
)

func generateRSAKeys() (*rsa.PrivateKey, error) {
    privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        return nil, err
    }
    return privateKey, nil
}

Step 2: Encrypt Data with Public Key

func encryptWithRSA(data []byte, publicKey *rsa.PublicKey) ([]byte, error) {
    encryptedData, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, data)
    if err != nil {
        return nil, err
    }
    return encryptedData, nil
}

Step 3: Decrypt Data with Private Key

func decryptWithRSA(encryptedData []byte, privateKey *rsa.PrivateKey) ([]byte, error) {
    decryptedData, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, encryptedData)
    if err != nil {
        return nil, err
    }
    return decryptedData, nil
}

Step 4: Example Usage

func main() {
    privateKey, _ := generateRSAKeys()
    publicKey := &privateKey.PublicKey
    data := []byte("Hello, World!")

    encryptedData, _ := encryptWithRSA(data, publicKey)
    fmt.Println("Encrypted:", base64.URLEncoding.EncodeToString(encryptedData))

    decryptedData, _ := decryptWithRSA(encryptedData, privateKey)
    fmt.Println("Decrypted:", string(decryptedData))
}

Hashing and Salting Passwords

Hashing is essential for securely storing passwords. We'll use the bcrypt package to hash and verify passwords.

Step 1: Import Required Packages

import (
    "golang.org/x/crypto/bcrypt"
)

Step 2: Hash a Password

func hashPassword(password string) (string, error) {
    hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
    if err != nil {
        return "", err
    }
    return string(hashedPassword), nil
}

Step 3: Verify a Password

func verifyPassword(hashedPassword, password string) error {
    return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
}

Step 4: Example Usage

func main() {
    password := "securepassword123"
    hashedPassword, _ := hashPassword(password)
    fmt.Println("Hashed Password:", hashedPassword)

    err := verifyPassword(hashedPassword, password)
    if err != nil {
        fmt.Println("Password verification failed")
    } else {
        fmt.Println("Password verified successfully")
    }
}

Best Practices for Security

  1. Use Strong Keys: Ensure keys are long and random.
  2. Secure Key Storage: Store encryption keys securely, preferably in environment variables or secure vaults.
  3. Regularly Rotate Keys: Change encryption keys periodically to minimize the risk of key compromise.
  4. Validate Inputs: Always validate user inputs to prevent injection attacks.
  5. Use Established Libraries: Leverage well-maintained cryptographic libraries like crypto and bcrypt.

Conclusion

In this tutorial, we explored how to implement encryption and decryption in Go using AES for symmetric encryption, RSA for asymmetric encryption, and bcrypt for password hashing. By following the best practices outlined, you can ensure that your applications handle sensitive data securely.

Remember, security is an ongoing process, and staying updated with the latest cryptographic standards and threats is crucial.


PreviousSecure Coding PracticesNext Authentication and Authorization

Recommended Gear

Secure Coding PracticesAuthentication and Authorization