Skip to main content
The crypto package collects common cryptographic constants and provides the interface for hash functions. It contains numerous subpackages implementing various cryptographic algorithms.

Key Subpackages

crypto/md5

MD5 hash algorithm. Note: MD5 is cryptographically broken and should not be used for security purposes.
import (
    "crypto/md5"
    "fmt"
    "io"
)

func hashMD5(data []byte) string {
    hash := md5.Sum(data)
    return fmt.Sprintf("%x", hash)
}

// Hash large data incrementally
func hashFileMD5(filename string) (string, error) {
    f, err := os.Open(filename)
    if err != nil {
        return "", err
    }
    defer f.Close()
    
    h := md5.New()
    if _, err := io.Copy(h, f); err != nil {
        return "", err
    }
    
    return fmt.Sprintf("%x", h.Sum(nil)), nil
}

crypto/sha256

SHA-256 and SHA-224 hash algorithms.
import "crypto/sha256"

func hashSHA256(data []byte) []byte {
    hash := sha256.Sum256(data)
    return hash[:]
}

// Incremental hashing
func hashIncrementalSHA256(parts [][]byte) []byte {
    h := sha256.New()
    for _, part := range parts {
        h.Write(part)
    }
    return h.Sum(nil)
}

crypto/sha512

SHA-512, SHA-384, SHA-512/224, and SHA-512/256 hash algorithms.
import "crypto/sha512"

func hashSHA512(data []byte) []byte {
    hash := sha512.Sum512(data)
    return hash[:]
}

crypto/rand

Cryptographically secure random number generator.
import (
    "crypto/rand"
    "encoding/base64"
    "math/big"
)

// Generate random bytes
func generateRandomBytes(n int) ([]byte, error) {
    b := make([]byte, n)
    _, err := rand.Read(b)
    return b, err
}

// Generate random string
func generateRandomString(length int) (string, error) {
    bytes, err := generateRandomBytes(length)
    if err != nil {
        return "", err
    }
    return base64.URLEncoding.EncodeToString(bytes)[:length], nil
}

// Generate random integer in range [0, max)
func generateRandomInt(max int64) (int64, error) {
    n, err := rand.Int(rand.Reader, big.NewInt(max))
    if err != nil {
        return 0, err
    }
    return n.Int64(), nil
}

crypto/aes

AES (Advanced Encryption Standard) block cipher.
import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
    "io"
)

// Encrypt with AES-GCM
func encryptAESGCM(plaintext, key []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    
    gcm, err := cipher.NewGCM(block)
    if err != nil {
        return nil, err
    }
    
    nonce := make([]byte, gcm.NonceSize())
    if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
        return nil, err
    }
    
    ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)
    return ciphertext, nil
}

// Decrypt with AES-GCM
func decryptAESGCM(ciphertext, key []byte) ([]byte, error) {
    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, errors.New("ciphertext too short")
    }
    
    nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
    return gcm.Open(nil, nonce, ciphertext, nil)
}

crypto/rsa

RSA encryption and signing.
import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/sha256"
)

// Generate RSA key pair
func generateRSAKeyPair(bits int) (*rsa.PrivateKey, error) {
    return rsa.GenerateKey(rand.Reader, bits)
}

// Encrypt with RSA-OAEP
func encryptRSA(plaintext []byte, publicKey *rsa.PublicKey) ([]byte, error) {
    return rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, plaintext, nil)
}

// Decrypt with RSA-OAEP
func decryptRSA(ciphertext []byte, privateKey *rsa.PrivateKey) ([]byte, error) {
    return rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, ciphertext, nil)
}

// Sign data
func signRSA(data []byte, privateKey *rsa.PrivateKey) ([]byte, error) {
    hashed := sha256.Sum256(data)
    return rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:])
}

// Verify signature
func verifyRSA(data, signature []byte, publicKey *rsa.PublicKey) error {
    hashed := sha256.Sum256(data)
    return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], signature)
}

crypto/ecdsa

Elliptic Curve Digital Signature Algorithm.
import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
    "crypto/sha256"
)

// Generate ECDSA key pair
func generateECDSAKeyPair() (*ecdsa.PrivateKey, error) {
    return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
}

// Sign data with ECDSA
func signECDSA(data []byte, privateKey *ecdsa.PrivateKey) ([]byte, []byte, error) {
    hash := sha256.Sum256(data)
    r, s, err := ecdsa.Sign(rand.Reader, privateKey, hash[:])
    if err != nil {
        return nil, nil, err
    }
    return r.Bytes(), s.Bytes(), nil
}

// Verify ECDSA signature
func verifyECDSA(data []byte, r, s []byte, publicKey *ecdsa.PublicKey) bool {
    hash := sha256.Sum256(data)
    rBig := new(big.Int).SetBytes(r)
    sBig := new(big.Int).SetBytes(s)
    return ecdsa.Verify(publicKey, hash[:], rBig, sBig)
}

crypto/hmac

Hash-based Message Authentication Code.
import (
    "crypto/hmac"
    "crypto/sha256"
)

func createHMAC(message, key []byte) []byte {
    h := hmac.New(sha256.New, key)
    h.Write(message)
    return h.Sum(nil)
}

func verifyHMAC(message, key, expectedMAC []byte) bool {
    mac := createHMAC(message, key)
    return hmac.Equal(mac, expectedMAC)
}

crypto/tls

TLS 1.2 and TLS 1.3 protocols.
import (
    "crypto/tls"
    "net/http"
)

// Create HTTPS server
func createHTTPSServer() error {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, HTTPS!"))
    })
    
    server := &http.Server{
        Addr:    ":443",
        Handler: mux,
        TLSConfig: &tls.Config{
            MinVersion: tls.VersionTLS12,
        },
    }
    
    return server.ListenAndServeTLS("cert.pem", "key.pem")
}

// Create HTTPS client with custom config
func createHTTPSClient() *http.Client {
    tlsConfig := &tls.Config{
        MinVersion:         tls.VersionTLS12,
        InsecureSkipVerify: false, // Don't skip verification in production!
    }
    
    transport := &http.Transport{
        TLSClientConfig: tlsConfig,
    }
    
    return &http.Client{
        Transport: transport,
    }
}

crypto/x509

X.509 certificates and certificate validation.
import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "crypto/x509/pkix"
    "encoding/pem"
    "math/big"
    "time"
)

// Create self-signed certificate
func createSelfSignedCert() ([]byte, []byte, error) {
    privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        return nil, nil, err
    }
    
    template := x509.Certificate{
        SerialNumber: big.NewInt(1),
        Subject: pkix.Name{
            Organization: []string{"My Company"},
            CommonName:   "localhost",
        },
        NotBefore:             time.Now(),
        NotAfter:              time.Now().Add(365 * 24 * time.Hour),
        KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
        ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
        BasicConstraintsValid: true,
    }
    
    certBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
    if err != nil {
        return nil, nil, err
    }
    
    certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certBytes})
    keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)})
    
    return certPEM, keyPEM, nil
}

Practical Examples

Password Hashing with bcrypt

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

func hashPassword(password string) (string, error) {
    bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
    return string(bytes), err
}

func checkPasswordHash(password, hash string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
    return err == nil
}

Secure Token Generation

import (
    "crypto/rand"
    "encoding/hex"
)

func generateSecureToken(length int) (string, error) {
    bytes := make([]byte, length)
    if _, err := rand.Read(bytes); err != nil {
        return "", err
    }
    return hex.EncodeToString(bytes), nil
}

File Encryption

func encryptFile(inputPath, outputPath string, key []byte) error {
    plaintext, err := os.ReadFile(inputPath)
    if err != nil {
        return err
    }
    
    ciphertext, err := encryptAESGCM(plaintext, key)
    if err != nil {
        return err
    }
    
    return os.WriteFile(outputPath, ciphertext, 0644)
}

func decryptFile(inputPath, outputPath string, key []byte) error {
    ciphertext, err := os.ReadFile(inputPath)
    if err != nil {
        return err
    }
    
    plaintext, err := decryptAESGCM(ciphertext, key)
    if err != nil {
        return err
    }
    
    return os.WriteFile(outputPath, plaintext, 0644)
}

Security Best Practices

  1. Use crypto/rand, not math/rand for cryptographic operations
  2. Don’t use MD5 or SHA-1 for security purposes (use SHA-256 or better)
  3. Always use authenticated encryption (like AES-GCM) instead of just encryption
  4. Use constant-time comparison (hmac.Equal, subtle.ConstantTimeCompare) to prevent timing attacks
  5. Generate random nonces/IVs for each encryption operation
  6. Use appropriate key sizes: AES-256 (32 bytes), RSA-2048+ bits
  7. Validate certificates in production (don’t use InsecureSkipVerify)
  8. Use standard libraries rather than implementing your own cryptography

Common Hash Functions

AlgorithmOutput SizeSecurity Status
MD5128 bitsBroken - avoid
SHA-1160 bitsBroken - avoid
SHA-224224 bitsSecure
SHA-256256 bitsSecure
SHA-384384 bitsSecure
SHA-512512 bitsSecure

Key Sizes

Symmetric Encryption

  • AES-128: 16 bytes (128 bits)
  • AES-192: 24 bytes (192 bits)
  • AES-256: 32 bytes (256 bits) - recommended

Asymmetric Encryption

  • RSA: Minimum 2048 bits, recommended 3072-4096 bits
  • ECDSA: P-256 (256 bits), P-384 (384 bits), P-521 (521 bits)

Build docs developers (and LLMs) love