🎯 Рекомендуемые коллекции
Балансированные коллекции примеров кода из различных категорий, которые вы можете исследовать
Примеры Криптографии Web Go
Примеры криптографии и безопасности Web Go включая вычисление хеша, симметричное шифрование и кодирование/декодирование Base64
💻 Вычисление Хеша go
🟢 simple
⭐⭐
Вычислять хеш MD5, SHA256 и другие для строк и файлов используя пакеты crypto Go
⏱️ 20 min
🏷️ go, web, cryptography
Prerequisites:
Basic Go, crypto package
// Web Go Hash Calculation Examples
// Using Go crypto packages for hash calculation
package main
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"fmt"
"hash"
"io"
"os"
)
// 1. String Hash Calculation
// CalculateMD5 calculates MD5 hash of a string
func CalculateMD5(input string) string {
hash := md5.Sum([]byte(input))
return hex.EncodeToString(hash[:])
}
// CalculateSHA1 calculates SHA1 hash of a string
func CalculateSHA1(input string) string {
hash := sha1.Sum([]byte(input))
return hex.EncodeToString(hash[:])
}
// CalculateSHA256 calculates SHA256 hash of a string
func CalculateSHA256(input string) string {
hash := sha256.Sum256([]byte(input))
return hex.EncodeToString(hash[:])
}
// CalculateSHA512 calculates SHA512 hash of a string
func CalculateSHA512(input string) string {
hash := sha512.Sum512([]byte(input))
return hex.EncodeToString(hash[:])
}
// CalculateHash calculates hash using specified algorithm
func CalculateHash(input string, algorithm string) (string, error) {
var h hash.Hash
switch algorithm {
case "md5":
h = md5.New()
case "sha1":
h = sha1.New()
case "sha256":
h = sha256.New()
case "sha512":
h = sha512.New()
default:
return "", fmt.Errorf("unsupported algorithm: %s", algorithm)
}
h.Write([]byte(input))
return hex.EncodeToString(h.Sum(nil)), nil
}
// CalculateMultipleHashes calculates multiple hashes of a string
func CalculateMultipleHashes(input string) map[string]string {
result := make(map[string]string)
result["md5"] = CalculateMD5(input)
result["sha1"] = CalculateSHA1(input)
result["sha256"] = CalculateSHA256(input)
result["sha512"] = CalculateSHA512(input)
return result
}
// 2. File Hash Calculation
// CalculateFileHash calculates hash of a file
func CalculateFileHash(filePath string, algorithm string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", fmt.Errorf("error opening file: %v", err)
}
defer file.Close()
var h hash.Hash
switch algorithm {
case "md5":
h = md5.New()
case "sha1":
h = sha1.New()
case "sha256":
h = sha256.New()
case "sha512":
h = sha512.New()
default:
return "", fmt.Errorf("unsupported algorithm: %s", algorithm)
}
if _, err := io.Copy(h, file); err != nil {
return "", fmt.Errorf("error reading file: %v", err)
}
return hex.EncodeToString(h.Sum(nil)), nil
}
// CalculateFileMD5 calculates MD5 hash of a file
func CalculateFileMD5(filePath string) (string, error) {
return CalculateFileHash(filePath, "md5")
}
// CalculateFileSHA256 calculates SHA256 hash of a file
func CalculateFileSHA256(filePath string) (string, error) {
return CalculateFileHash(filePath, "sha256")
}
// CalculateFileHashWithProgress calculates file hash with progress tracking
func CalculateFileHashWithProgress(filePath string, algorithm string, progressCallback func(written, total int64)) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", fmt.Errorf("error opening file: %v", err)
}
defer file.Close()
info, err := file.Stat()
if err != nil {
return "", fmt.Errorf("error getting file info: %v", err)
}
var h hash.Hash
switch algorithm {
case "md5":
h = md5.New()
case "sha1":
h = sha1.New()
case "sha256":
h = sha256.New()
case "sha512":
h = sha512.New()
default:
return "", fmt.Errorf("unsupported algorithm: %s", algorithm)
}
// Copy with progress
buffer := make([]byte, 32*1024) // 32KB buffer
var written int64
for {
n, err := file.Read(buffer)
if n > 0 {
h.Write(buffer[:n])
written += int64(n)
if progressCallback != nil {
progressCallback(written, info.Size())
}
}
if err != nil {
if err == io.EOF {
break
}
return "", fmt.Errorf("error reading file: %v", err)
}
}
return hex.EncodeToString(h.Sum(nil)), nil
}
// 3. Hash Comparison
// VerifyHash verifies if a string matches the expected hash
func VerifyHash(input, expectedHash, algorithm string) (bool, error) {
calculatedHash, err := CalculateHash(input, algorithm)
if err != nil {
return false, err
}
return calculatedHash == expectedHash, nil
}
// VerifyFileHash verifies if a file matches the expected hash
func VerifyFileHash(filePath, expectedHash, algorithm string) (bool, error) {
calculatedHash, err := CalculateFileHash(filePath, algorithm)
if err != nil {
return false, err
}
return calculatedHash == expectedHash, nil
}
// 4. HMAC Calculation
import (
"crypto/hmac"
)
// CalculateHMAC calculates HMAC using specified hash algorithm
func CalculateHMAC(key, message, algorithm string) (string, error) {
var h func() hash.Hash
switch algorithm {
case "md5":
h = md5.New
case "sha1":
h = sha1.New
case "sha256":
h = sha256.New
case "sha512":
h = sha512.New
default:
return "", fmt.Errorf("unsupported algorithm: %s", algorithm)
}
mac := hmac.New(h, []byte(key))
mac.Write([]byte(message))
return hex.EncodeToString(mac.Sum(nil)), nil
}
// VerifyHMAC verifies HMAC signature
func VerifyHMAC(key, message, expectedMAC, algorithm string) (bool, error) {
calculatedMAC, err := CalculateHMAC(key, message, algorithm)
if err != nil {
return false, err
}
// Use constant-time comparison to prevent timing attacks
return hmac.Equal([]byte(calculatedMAC), []byte(expectedMAC)), nil
}
// 5. Hash Utilities
// GenerateHashFromBytes calculates hash from byte slice
func GenerateHashFromBytes(data []byte, algorithm string) (string, error) {
var h hash.Hash
switch algorithm {
case "md5":
h = md5.New()
case "sha1":
h = sha1.New()
case "sha256":
h = sha256.New()
case "sha512":
h = sha512.New()
default:
return "", fmt.Errorf("unsupported algorithm: %s", algorithm)
}
h.Write(data)
return hex.EncodeToString(h.Sum(nil)), nil
}
// HashFormat formats hash string with specified casing and separator
func HashFormat(hash string, uppercase bool, separator string, chunkSize int) string {
if uppercase {
hash = strings.ToUpper(hash)
}
if chunkSize > 0 && separator != "" {
var parts []string
for i := 0; i < len(hash); i += chunkSize {
end := i + chunkSize
if end > len(hash) {
end = len(hash)
}
parts = append(parts, hash[i:end])
}
return strings.Join(parts, separator)
}
return hash
}
// Usage Examples
func main() {
fmt.Println("=== Web Go Hash Calculation Examples ===\n")
// 1. String hash calculation
fmt.Println("--- 1. String Hash Calculation ---")
text := "Hello, World!"
fmt.Printf("MD5: %s\n", CalculateMD5(text))
fmt.Printf("SHA1: %s\n", CalculateSHA1(text))
fmt.Printf("SHA256: %s\n", CalculateSHA256(text))
fmt.Printf("SHA512: %s\n", CalculateSHA512(text))
// 2. Multiple hashes
fmt.Println("\n--- 2. Multiple Hashes ---")
hashes := CalculateMultipleHashes(text)
for algo, hash := range hashes {
fmt.Printf("%s: %s\n", strings.ToUpper(algo), hash)
}
// 3. File hash
fmt.Println("\n--- 3. File Hash ---")
fileHash, err := CalculateFileSHA256("example.txt")
if err == nil {
fmt.Printf("File SHA256: %s\n", fileHash)
}
// 4. Hash verification
fmt.Println("\n--- 4. Hash Verification ---")
expectedHash := CalculateSHA256(text)
valid, _ := VerifyHash(text, expectedHash, "sha256")
fmt.Printf("Hash valid: %v\n", valid)
// 5. HMAC
fmt.Println("\n--- 5. HMAC Calculation ---")
key := "secret-key"
message := "authenticated message"
hmac, err := CalculateHMAC(key, message, "sha256")
if err == nil {
fmt.Printf("HMAC-SHA256: %s\n", hmac)
}
// 6. Hash with progress
fmt.Println("\n--- 6. File Hash with Progress ---")
_, err = CalculateFileHashWithProgress("large_file.bin", "sha256", func(written, total int64) {
fmt.Printf("Progress: %.1f%%\n", float64(written)/float64(total)*100)
})
if err == nil {
fmt.Println("File hash calculated")
}
fmt.Println("\n=== All Hash Calculation Examples Completed ===")
}
💻 Кодирование/Декодирование Base64 go
🟢 simple
⭐⭐
Кодирование и декодирование Base64 и Base64URL для строк и бинарных данных
⏱️ 15 min
🏷️ go, web, cryptography, encoding
Prerequisites:
Basic Go, encoding/base64
// Web Go Base64 Encoding Examples
// Base64 and Base64URL encoding and decoding
package main
import (
"encoding/base64"
"fmt"
"strings"
)
// 1. Basic Base64 Encoding
// EncodeBase64 encodes a string to Base64
func EncodeBase64(input string) string {
return base64.StdEncoding.EncodeToString([]byte(input))
}
// DecodeBase64 decodes a Base64 string
func DecodeBase64(input string) (string, error) {
data, err := base64.StdEncoding.DecodeString(input)
if err != nil {
return "", fmt.Errorf("error decoding Base64: %v", err)
}
return string(data), nil
}
// EncodeBase64Bytes encodes bytes to Base64
func EncodeBase64Bytes(data []byte) string {
return base64.StdEncoding.EncodeToString(data)
}
// DecodeBase64Bytes decodes Base64 to bytes
func DecodeBase64Bytes(input string) ([]byte, error) {
data, err := base64.StdEncoding.DecodeString(input)
if err != nil {
return nil, fmt.Errorf("error decoding Base64: %v", err)
}
return data, nil
}
// 2. URL-Safe Base64 Encoding
// EncodeBase64URL encodes a string to URL-safe Base64
func EncodeBase64URL(input string) string {
return base64.URLEncoding.EncodeToString([]byte(input))
}
// DecodeBase64URL decodes a URL-safe Base64 string
func DecodeBase64URL(input string) (string, error) {
data, err := base64.URLEncoding.DecodeString(input)
if err != nil {
return "", fmt.Errorf("error decoding Base64URL: %v", err)
}
return string(data), nil
}
// EncodeBase64URLBytes encodes bytes to URL-safe Base64
func EncodeBase64URLBytes(data []byte) string {
return base64.URLEncoding.EncodeToString(data)
}
// DecodeBase64URLBytes decodes URL-safe Base64 to bytes
func DecodeBase64URLBytes(input string) ([]byte, error) {
data, err := base64.URLEncoding.DecodeString(input)
if err != nil {
return nil, fmt.Errorf("error decoding Base64URL: %v", err)
}
return data, nil
}
// 3. Raw Base64 Encoding (No padding)
// EncodeBase64Raw encodes a string to raw Base64 (no padding)
func EncodeBase64Raw(input string) string {
return base64.RawStdEncoding.EncodeToString([]byte(input))
}
// DecodeBase64Raw decodes a raw Base64 string
func DecodeBase64Raw(input string) (string, error) {
data, err := base64.RawStdEncoding.DecodeString(input)
if err != nil {
return "", fmt.Errorf("error decoding raw Base64: %v", err)
}
return string(data), nil
}
// EncodeBase64URLRaw encodes a string to raw URL-safe Base64
func EncodeBase64URLRaw(input string) string {
return base64.RawURLEncoding.EncodeToString([]byte(input))
}
// DecodeBase64URLRaw decodes a raw URL-safe Base64 string
func DecodeBase64URLRaw(input string) (string, error) {
data, err := base64.RawURLEncoding.DecodeString(input)
if err != nil {
return "", fmt.Errorf("error decoding raw Base64URL: %v", err)
}
return string(data), nil
}
// 4. Base64 with Custom Encoding
// EncodeBase64WithPadding encodes with optional padding
func EncodeBase64WithPadding(input string, withPadding bool) string {
data := []byte(input)
if withPadding {
return base64.StdEncoding.EncodeToString(data)
}
return base64.RawStdEncoding.EncodeToString(data)
}
// DecodeBase64Auto decodes Base64 with or without padding
func DecodeBase64Auto(input string) (string, error) {
// Try StdEncoding first
data, err := base64.StdEncoding.DecodeString(input)
if err == nil {
return string(data), nil
}
// Try RawStdEncoding
data, err = base64.RawStdEncoding.DecodeString(input)
if err == nil {
return string(data), nil
}
return "", fmt.Errorf("failed to decode Base64")
}
// 5. Base64 Validation
// IsValidBase64 checks if a string is valid Base64
func IsValidBase64(input string) bool {
_, err := base64.StdEncoding.DecodeString(input)
return err == nil
}
// IsValidBase64URL checks if a string is valid URL-safe Base64
func IsValidBase64URL(input string) bool {
_, err := base64.URLEncoding.DecodeString(input)
return err == nil
}
// DetectBase64Type detects the type of Base64 encoding
func DetectBase64Type(input string) string {
// Check for URL-safe characters
if strings.ContainsAny(input, "-_") {
if !strings.HasSuffix(input, "=") && !strings.HasSuffix(input, "==") {
return "Base64URL (Raw)"
}
return "Base64URL"
}
// Check for standard Base64
if !strings.HasSuffix(input, "=") && !strings.HasSuffix(input, "==") {
return "Base64 (Raw)"
}
return "Base64 (Standard)"
}
// 6. Base64 Utilities
// Base64EncodeChunked encodes with line wrapping
func Base64EncodeChunked(input string, chunkSize int) []string {
encoded := base64.StdEncoding.EncodeToString([]byte(input))
var chunks []string
for i := 0; i < len(encoded); i += chunkSize {
end := i + chunkSize
if end > len(encoded) {
end = len(encoded)
}
chunks = append(chunks, encoded[i:end])
}
return chunks
}
// RemoveBase64Padding removes padding from Base64 string
func RemoveBase64Padding(input string) string {
return strings.TrimRight(input, "=")
}
// AddBase64Padding adds padding to Base64 string
func AddBase64Padding(input string) string {
padding := len(input) % 4
if padding != 0 {
input += strings.Repeat("=", 4-padding)
}
return input
}
// 7. Batch Operations
// EncodeBatch encodes multiple strings
func EncodeBatch(inputs []string) map[string]string {
results := make(map[string]string)
for _, input := range inputs {
results[input] = EncodeBase64(input)
}
return results
}
// DecodeBatch decodes multiple Base64 strings
func DecodeBatch(inputs map[string]string) (map[string]string, error) {
results := make(map[string]string)
for key, encoded := range inputs {
decoded, err := DecodeBase64(encoded)
if err != nil {
return nil, err
}
results[key] = decoded
}
return results, nil
}
// 8. File Operations
// EncodeFileToBase64 encodes a file to Base64
func EncodeFileToBase64(filePath string) (string, error) {
data, err := os.ReadFile(filePath)
if err != nil {
return "", fmt.Errorf("error reading file: %v", err)
}
return base64.StdEncoding.EncodeToString(data), nil
}
// DecodeBase64ToFile decodes Base64 and writes to file
func DecodeBase64ToFile(encoded, filePath string) error {
data, err := base64.StdEncoding.DecodeString(encoded)
if err != nil {
return fmt.Errorf("error decoding Base64: %v", err)
}
err = os.WriteFile(filePath, data, 0644)
if err != nil {
return fmt.Errorf("error writing file: %v", err)
}
return nil
}
// 9. Specialized Encoding
// EncodeDataURL creates a data URL (for web use)
func EncodeDataURL mimeType, data string) string {
encoded := base64.StdEncoding.EncodeToString([]byte(data))
return fmt.Sprintf("data:%s;base64,%s", mimeType, encoded)
}
// EncodeImageDataURL creates a data URL for images
func EncodeImageDataURL(imageData []byte, mimeType string) string {
encoded := base64.StdEncoding.EncodeToString(imageData)
return fmt.Sprintf("data:%s;base64,%s", mimeType, encoded)
}
// Usage Examples
func main() {
fmt.Println("=== Web Go Base64 Encoding Examples ===\n")
// 1. Basic encoding
fmt.Println("--- 1. Basic Base64 ---")
text := "Hello, World!"
encoded := EncodeBase64(text)
fmt.Printf("Encoded: %s\n", encoded)
decoded, _ := DecodeBase64(encoded)
fmt.Printf("Decoded: %s\n", decoded)
// 2. URL-safe encoding
fmt.Println("\n--- 2. URL-Safe Base64 ---")
urlText := "Hello?name=value&data=test"
urlEncoded := EncodeBase64URL(urlText)
fmt.Printf("URL Encoded: %s\n", urlEncoded)
urlDecoded, _ := DecodeBase64URL(urlEncoded)
fmt.Printf("URL Decoded: %s\n", urlDecoded)
// 3. Raw encoding (no padding)
fmt.Println("\n--- 3. Raw Base64 ---")
rawEncoded := EncodeBase64Raw(text)
fmt.Printf("Raw Encoded: %s\n", rawEncoded)
rawDecoded, _ := DecodeBase64Raw(rawEncoded)
fmt.Printf("Raw Decoded: %s\n", rawDecoded)
// 4. Validation
fmt.Println("\n--- 4. Validation ---")
fmt.Printf("Valid Base64: %v\n", IsValidBase64(encoded))
fmt.Printf("Valid URL Base64: %v\n", IsValidBase64URL(urlEncoded))
fmt.Printf("Type: %s\n", DetectBase64Type(encoded))
// 5. Padding operations
fmt.Println("\n--- 5. Padding Operations ---")
noPadding := RemoveBase64Padding(encoded)
fmt.Printf("Without padding: %s\n", noPadding)
withPadding := AddBase64Padding(noPadding)
fmt.Printf("With padding: %s\n", withPadding)
// 6. Chunked encoding
fmt.Println("\n--- 6. Chunked Encoding ---")
chunks := Base64EncodeChunked("This is a longer string for chunked encoding", 20)
fmt.Printf("Chunks: %d\n", len(chunks))
for i, chunk := range chunks {
fmt.Printf(" Chunk %d: %s\n", i+1, chunk)
}
// 7. Batch encoding
fmt.Println("\n--- 7. Batch Encoding ---")
batchInputs := []string{"text1", "text2", "text3"}
batchResults := EncodeBatch(batchInputs)
fmt.Printf("Encoded %d items\n", len(batchResults))
// 8. Data URL
fmt.Println("\n--- 8. Data URL ---")
dataURL := EncodeDataURL("text/plain", text)
fmt.Printf("Data URL: %s\n", dataURL[:50]+"...")
fmt.Println("\n=== All Base64 Encoding Examples Completed ===")
}
💻 Симметричное Шифрование (AES) go
🟡 intermediate
⭐⭐⭐⭐
Шифрование и дешифрование AES с различными режимами (CBC, GCM, CTR) используя пакеты crypto Go
⏱️ 30 min
🏷️ go, web, cryptography, encryption
Prerequisites:
Intermediate Go, crypto/aes, crypto/cipher
// Web Go Symmetric Encryption Examples
// AES encryption and decryption with different modes
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"io"
"strings"
)
// 1. AES-GCM Encryption (Recommended)
// EncryptGCM encrypts plaintext using AES-GCM
func EncryptGCM(plaintext, key []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", fmt.Errorf("error creating cipher: %v", err)
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return "", fmt.Errorf("error creating GCM: %v", err)
}
// Generate random nonce
nonce := make([]byte, gcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return "", fmt.Errorf("error generating nonce: %v", err)
}
// Encrypt and authenticate
ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)
// Encode to base64
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// DecryptGCM decrypts ciphertext using AES-GCM
func DecryptGCM(ciphertext string, key []byte) ([]byte, error) {
// Decode from base64
data, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return nil, fmt.Errorf("error decoding ciphertext: %v", err)
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("error creating cipher: %v", err)
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, fmt.Errorf("error creating GCM: %v", err)
}
nonceSize := gcm.NonceSize()
if len(data) < nonceSize {
return nil, errors.New("ciphertext too short")
}
nonce, cipherData := data[:nonceSize], data[nonceSize:]
// Decrypt and verify
plaintext, err := gcm.Open(nil, nonce, cipherData, nil)
if err != nil {
return nil, fmt.Errorf("error decrypting: %v", err)
}
return plaintext, nil
}
// 2. AES-CBC Encryption
// EncryptCBCEncrypts plaintext using AES-CBC with PKCS7 padding
func EncryptCBC(plaintext, key, iv []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", fmt.Errorf("error creating cipher: %v", err)
}
// PKCS7 padding
padding := aes.BlockSize - len(plaintext)%aes.BlockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
plaintext = append(plaintext, padtext...)
if len(iv) != aes.BlockSize {
return "", errors.New("incorrect IV length")
}
ciphertext := make([]byte, len(plaintext))
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, plaintext)
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// DecryptCBC decrypts ciphertext using AES-CBC
func DecryptCBC(ciphertext string, key, iv []byte) ([]byte, error) {
// Decode from base64
data, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return nil, fmt.Errorf("error decoding ciphertext: %v", err)
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("error creating cipher: %v", err)
}
if len(iv) != aes.BlockSize {
return nil, errors.New("incorrect IV length")
}
if len(data)%aes.BlockSize != 0 {
return nil, errors.New("ciphertext is not a multiple of the block size")
}
plaintext := make([]byte, len(data))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(plaintext, data)
// Remove PKCS7 padding
padding := int(plaintext[len(plaintext)-1])
if padding > aes.BlockSize || padding > len(plaintext) {
return nil, errors.New("invalid padding")
}
return plaintext[:len(plaintext)-padding], nil
}
// 3. AES-CTR Encryption (Stream Cipher)
// EncryptCTR encrypts plaintext using AES-CTR
func EncryptCTR(plaintext, key, iv []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", fmt.Errorf("error creating cipher: %v", err)
}
if len(iv) != aes.BlockSize {
return "", errors.New("incorrect IV length")
}
ciphertext := make([]byte, len(plaintext))
stream := cipher.NewCTR(block, iv)
stream.XORKeyStream(ciphertext, plaintext)
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// DecryptCTR decrypts ciphertext using AES-CTR
func DecryptCTR(ciphertext string, key, iv []byte) ([]byte, error) {
// Decode from base64
data, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return nil, fmt.Errorf("error decoding ciphertext: %v", err)
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("error creating cipher: %v", err)
}
if len(iv) != aes.BlockSize {
return nil, errors.New("incorrect IV length")
}
plaintext := make([]byte, len(data))
stream := cipher.NewCTR(block, iv)
stream.XORKeyStream(plaintext, data)
return plaintext, nil
}
// 4. Key Management
// GenerateRandomKey generates a random encryption key
func GenerateRandomKey(size int) ([]byte, error) {
key := make([]byte, size)
if _, err := io.ReadFull(rand.Reader, key); err != nil {
return nil, fmt.Errorf("error generating key: %v", err)
}
return key, nil
}
// GenerateAES128Key generates a 128-bit AES key
func GenerateAES128Key() ([]byte, error) {
return GenerateRandomKey(16)
}
// GenerateAES192Key generates a 192-bit AES key
func GenerateAES192Key() ([]byte, error) {
return GenerateRandomKey(24)
}
// GenerateAES256Key generates a 256-bit AES key
func GenerateAES256Key() ([]byte, error) {
return GenerateRandomKey(32)
}
// GenerateRandomIV generates a random IV
func GenerateRandomIV() ([]byte, error) {
iv := make([]byte, aes.BlockSize)
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, fmt.Errorf("error generating IV: %v", err)
}
return iv, nil
}
// 5. High-Level Encryption Functions
// EncryptString encrypts a string using AES-GCM with a generated key
func EncryptString(plaintext string) (string, string, error) {
key, err := GenerateAES256Key()
if err != nil {
return "", "", err
}
ciphertext, err := EncryptGCM([]byte(plaintext), key)
if err != nil {
return "", "", err
}
// Encode key as hex for storage
keyHex := hex.EncodeToString(key)
return ciphertext, keyHex, nil
}
// DecryptString decrypts a string using the provided key
func DecryptString(ciphertext, keyHex string) (string, error) {
key, err := hex.DecodeString(keyHex)
if err != nil {
return "", fmt.Errorf("error decoding key: %v", err)
}
plaintext, err := DecryptGCM(ciphertext, key)
if err != nil {
return "", err
}
return string(plaintext), nil
}
// 6. Batch Encryption
// EncryptBatch encrypts multiple strings
func EncryptBatch(messages []string, key []byte) (map[string]string, error) {
results := make(map[string]string)
for _, msg := range messages {
ciphertext, err := EncryptGCM([]byte(msg), key)
if err != nil {
return nil, err
}
results[msg] = ciphertext
}
return results, nil
}
// DecryptBatch decrypts multiple strings
func DecryptBatch(ciphertexts map[string]string, key []byte) (map[string]string, error) {
results := make(map[string]string)
for id, ciphertext := range ciphertexts {
plaintext, err := DecryptGCM(ciphertext, key)
if err != nil {
return nil, err
}
results[id] = string(plaintext)
}
return results, nil
}
// 7. File Encryption
// EncryptFile encrypts a file
func EncryptFile(inputPath, outputPath string, key []byte) error {
plaintext, err := os.ReadFile(inputPath)
if err != nil {
return fmt.Errorf("error reading file: %v", err)
}
ciphertext, err := EncryptGCM(plaintext, key)
if err != nil {
return err
}
return os.WriteFile(outputPath, []byte(ciphertext), 0644)
}
// DecryptFile decrypts a file
func DecryptFile(inputPath, outputPath string, key []byte) error {
data, err := os.ReadFile(inputPath)
if err != nil {
return fmt.Errorf("error reading file: %v", err)
}
plaintext, err := DecryptGCM(string(data), key)
if err != nil {
return err
}
return os.WriteFile(outputPath, plaintext, 0644)
}
// Usage Examples
func main() {
fmt.Println("=== Web Go Symmetric Encryption Examples ===\n")
// 1. AES-GCM encryption
fmt.Println("--- 1. AES-GCM Encryption ---")
key, _ := GenerateAES256Key()
plaintext := "Secret message"
ciphertext, err := EncryptGCM([]byte(plaintext), key)
if err == nil {
fmt.Printf("Encrypted: %s\n", ciphertext[:50]+"...")
}
decrypted, err := DecryptGCM(ciphertext, key)
if err == nil {
fmt.Printf("Decrypted: %s\n", string(decrypted))
}
// 2. String encryption with key generation
fmt.Println("\n--- 2. String Encryption ---")
msg := "Important data"
encrypted, keyHex, _ := EncryptString(msg)
fmt.Printf("Encrypted: %s\n", encrypted[:50]+"...")
fmt.Printf("Key: %s\n", keyHex)
decrypted, _ = DecryptString(encrypted, keyHex)
fmt.Printf("Decrypted: %s\n", decrypted)
// 3. AES-CBC encryption
fmt.Println("\n--- 3. AES-CBC Encryption ---")
iv, _ := GenerateRandomIV()
cbcCipher, _ := EncryptCBC([]byte("CBC Mode"), key, iv)
fmt.Printf("CBC Encrypted: %s\n", cbcCipher[:50]+"...")
// 4. Batch encryption
fmt.Println("\n--- 4. Batch Encryption ---")
messages := []string{"msg1", "msg2", "msg3"}
batchResults, _ := EncryptBatch(messages, key)
fmt.Printf("Encrypted %d messages\n", len(batchResults))
// 5. Key sizes
fmt.Println("\n--- 5. Key Sizes ---")
key128, _ := GenerateAES128Key()
key192, _ := GenerateAES192Key()
key256, _ := GenerateAES256Key()
fmt.Printf("AES-128: %d bits\n", len(key128)*8)
fmt.Printf("AES-192: %d bits\n", len(key192)*8)
fmt.Printf("AES-256: %d bits\n", len(key256)*8)
fmt.Println("\n=== All Symmetric Encryption Examples Completed ===")
}