aesgcm

package
v2.0.91 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 9, 2026 License: MIT Imports: 11 Imported by: 0

README

AES-GCM 加密库

使用示例

// package_example.go
package aesgcm

// 使用指南示例代码,展示不同方法的使用场景

// ExampleUsage 展示不同加密方法的使用场景
func ExampleUsage() {
	// 场景1: 基础加密 - 适用于大多数简单加密需求
	func ExampleBasicEncryption() {
		key, _ := GenerateKey(AES256)
		crypto, _ := NewAESGCM(key)
		
		// 加密普通数据
		plaintext := "敏感数据"
		ciphertext, _ := crypto.Encrypt([]byte(plaintext))
		
		// 解密
		decrypted, _ := crypto.Decrypt(ciphertext)
		_ = string(decrypted)
	}

	// 场景2: 字符串加密 - 适用于需要字符串输出的场景
	func ExampleStringEncryption() {
		key, _ := GenerateKey(AES256)
		crypto, _ := NewAESGCM(key)
		
		// 加密为base64字符串,适合存储到数据库
		encoded, _ := crypto.EncryptToString("用户密码")
		
		// 从base64字符串解密
		decrypted, _ := crypto.DecryptFromString(encoded)
		_ = decrypted
	}

	// 场景3: 带附加数据的加密 - 适用于需要认证额外元数据的场景
	func ExampleAdditionalDataEncryption() {
		key, _ := GenerateKey(AES256)
		crypto, _ := NewAESGCM(key)
		
		// 加密消息体,同时认证消息头
		message := "消息内容"
		headers := []byte("消息类型:私密;发送者:Alice")
		
		ciphertext, _ := crypto.EncryptWithAdditionalData(
			[]byte(message), 
			headers,
		)
		
		// 解密时必须提供相同的消息头,否则会失败
		decrypted, _ := crypto.DecryptWithAdditionalData(ciphertext, headers)
		_ = string(decrypted)
	}

	// 场景4: 从配置创建实例 - 适用于从环境变量读取密钥
	func ExampleFromConfig() {
		// 假设从环境变量读取密钥
		keyStr := "my-secret-key-32-bytes-long-keys!"
		crypto, _ := NewAESGCMFromString(keyStr, AES256)
		
		ciphertext, _ := crypto.EncryptToString("配置数据")
		_ = ciphertext
	}
}

选择加密方法的指南

  1. 基础需求 - 使用 Encrypt/Decrypt:

    • 简单的数据加密
    • 不需要额外的认证数据
    • 处理二进制数据
  2. 字符串存储 - 使用 EncryptToString/DecryptFromString:

    • 加密结果需要存储到数据库
    • 需要在JSON/XML中传输加密数据
    • URL参数传递
  3. 高级认证 - 使用 EncryptWithAdditsionalData/DecryptWithAdditionalData:

    • 需要保护消息头或元数据
    • 加密数据有关联的上下文信息
    • 需要额外的数据完整性验证
  4. 密钥生成建议:

    • 高安全性: 使用 Generate256Key() 或 GenerateKey(AES256)
    • 性能优先: 使用 Generate128Key() 或 GenerateKey(AES128)
    • 兼容性: 使用 GenerateKey() 并指定合适的密钥长度

Documentation

Overview

doc.go

Example (AdditionalData)

Example_additionalData 展示附加数据的使用

package main

import (
	"fmt"
	"log"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	key, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAESGCM(key)

	// 消息内容
	message := "转账给Bob: 1000元"
	// 消息头(不会被加密,但参与认证)
	headers := []byte("交易类型:转账;时间戳:2024-01-01")

	// 使用附加数据加密
	ciphertext, err := crypto.EncryptWithAdditionalData([]byte(message), headers)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("加密成功,包含消息头认证\n")

	// 解密时必须提供相同的消息头
	decrypted, err := crypto.DecryptWithAdditionalData(ciphertext, headers)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("解密成功: %s\n", string(decrypted))

	// 尝试使用错误的头信息解密(会失败)
	wrongHeaders := []byte("交易类型:查询")
	_, err = crypto.DecryptWithAdditionalData(ciphertext, wrongHeaders)
	if err != nil {
		fmt.Printf("认证失败: %v\n", err)
	}
}
Output:

加密成功,包含消息头认证
解密成功: 转账给Bob: 1000元
认证失败: decryption failed: authentication failed
Example (Base64Encoding)

Example_base64Encoding 展示Base64编码的使用场景

package main

import (
	"fmt"
	"strings"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	key, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAESGCM(key)

	// 场景1: 存储到数据库
	userPassword := "mySecretPassword123"
	encryptedForDB, _ := crypto.EncryptToString(userPassword)

	// 场景2: URL安全传输
	apiKey := "api_key_123456789"
	encryptedForURL, _ := crypto.EncryptToString(apiKey)

	// 场景3: JSON序列化
	configData := `{"server": "api.example.com", "port": 443}`
	encryptedForJSON, _ := crypto.EncryptToString(configData)

	// 验证解密功能
	decrypted1, _ := crypto.DecryptFromString(encryptedForDB)
	decrypted2, _ := crypto.DecryptFromString(encryptedForURL)
	decrypted3, _ := crypto.DecryptFromString(encryptedForJSON)

	success := strings.Contains(decrypted1, "Password") &&
		strings.Contains(decrypted2, "api_key") &&
		strings.Contains(decrypted3, "example.com")

	fmt.Printf("Base64编码加解密验证: %v\n", success)
}
Output:

Base64编码加解密验证: true
Example (BasicUsage)

Example_basicUsage 展示基础用法

package main

import (
	"fmt"
	"log"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 生成256位密钥(推荐用于生产环境)
	key, err := aesgcm.GenerateKey(aesgcm.AES256)
	if err != nil {
		log.Fatal(err)
	}

	// 创建加密器实例
	crypto, err := aesgcm.NewAESGCM(key)
	if err != nil {
		log.Fatal(err)
	}

	// 加密数据
	plaintext := "这是一段敏感数据,需要安全存储"
	ciphertext, err := crypto.Encrypt([]byte(plaintext))
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("加密成功\n")

	// 解密数据
	decrypted, err := crypto.Decrypt(ciphertext)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("解密成功: %s\n", string(decrypted))
}
Output:

加密成功
解密成功: 这是一段敏感数据,需要安全存储
Example (CompareWithCBC)

Example_compareWithCBC 展示GCM与CBC的对比

package main

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"
	"fmt"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	key, _ := aesgcm.GenerateKey(aesgcm.AES256)
	data := "需要加密的数据"

	fmt.Println("=== AES-GCM 方式 ===")
	// GCM - 一步完成加密和认证
	gcm, _ := aesgcm.NewAESGCM(key)
	gcmCiphertext, _ := gcm.Encrypt([]byte(data))
	gcmDecrypted, _ := gcm.Decrypt(gcmCiphertext)
	fmt.Printf("GCM解密: %s\n", string(gcmDecrypted))

	fmt.Println("=== AES-CBC+HMAC 方式 ===")
	// CBC + HMAC - 需要多个步骤
	block, _ := aes.NewCipher(key)

	// 加密
	iv := make([]byte, aes.BlockSize)
	rand.Read(iv)
	mode := cipher.NewCBCEncrypter(block, iv)
	paddedData := pkcs7Pad([]byte(data), aes.BlockSize)
	cbcCiphertext := make([]byte, len(paddedData))
	mode.CryptBlocks(cbcCiphertext, paddedData)

	// 计算HMAC(需要额外的密钥)
	macKey := make([]byte, 32)
	rand.Read(macKey)
	h := hmac.New(sha256.New, macKey)
	h.Write(cbcCiphertext)
	mac := h.Sum(nil)

	// 组合结果: IV + ciphertext + MAC
	finalCiphertext := append(iv, append(cbcCiphertext, mac...)...)

	// 解密过程同样复杂...
	fmt.Printf("CBC+HMAC完成,结果长度: %d\n", len(finalCiphertext))

	fmt.Println("=== 总结 ===")
	fmt.Println("GCM优势:")
	fmt.Println("  - 单一步骤完成加密和认证")
	fmt.Println("  - 无需填充处理")
	fmt.Println("  - 代码更简洁")
	fmt.Println("  - 性能通常更好")
}

// pkcs7Pad PKCS7填充函数
func pkcs7Pad(data []byte, blockSize int) []byte {
	padding := blockSize - len(data)%blockSize
	padtext := make([]byte, padding)
	for i := range padtext {
		padtext[i] = byte(padding)
	}
	return append(data, padtext...)
}
Example (Comprehensive)

Example_comprehensive 综合示例

package main

import (
	"fmt"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 1. 密钥生成和管理
	key, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAESGCM(key)

	// 2. 基础加密解密
	data1 := "普通数据"
	encrypted1, _ := crypto.Encrypt([]byte(data1))
	decrypted1, _ := crypto.Decrypt(encrypted1)

	// 3. 字符串加密解密
	data2 := "字符串数据"
	encryptedStr, _ := crypto.EncryptToString(data2)
	decryptedStr, _ := crypto.DecryptFromString(encryptedStr)

	// 4. 带附加数据的加密
	data3 := "敏感数据"
	additionalData := []byte("元数据")
	encryptedWithAD, _ := crypto.EncryptWithAdditionalData([]byte(data3), additionalData)
	decryptedWithAD, _ := crypto.DecryptWithAdditionalData(encryptedWithAD, additionalData)

	// 验证所有功能正常
	allSuccess := string(decrypted1) == data1 &&
		decryptedStr == data2 &&
		string(decryptedWithAD) == data3

	fmt.Printf("AES-GCM所有功能测试: %v\n", allSuccess)
}
Output:

AES-GCM所有功能测试: true
Example (DifferentKeySizes)

Example_differentKeySizes 展示不同密钥长度的使用

package main

import (
	"fmt"
	"log"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 场景1: 高安全性需求 - 使用AES-256
	key256, _ := aesgcm.GenerateKey(aesgcm.AES256)
	crypto256, _ := aesgcm.NewAESGCM(key256)
	_, err := crypto256.EncryptToString("高度敏感数据")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("AES-256加密成功\n")

	// 场景2: 性能敏感 - 使用AES-128
	key128, _ := aesgcm.GenerateKey(aesgcm.AES128)
	crypto128, _ := aesgcm.NewAESGCM(key128)
	_, err = crypto128.EncryptToString("普通敏感数据")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("AES-128加密成功\n")

	// 场景3: 从字符串密钥创建 - 使用确切的32字节字符串
	keyStr := "0123456789abcdef0123456789abcdef" // 确切的32字节
	cryptoFromStr, err := aesgcm.NewAESGCMFromString(keyStr, aesgcm.AES256)
	if err != nil {
		log.Fatal(err)
	}
	_, err = cryptoFromStr.EncryptToString("配置数据")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("字符串密钥加密成功\n")
}
Output:

AES-256加密成功
AES-128加密成功
字符串密钥加密成功
Example (DifferentKeySizesFormatted)

Example_differentKeySizesFormatted 展示不同密钥长度的格式化字符串

package main

import (
	"fmt"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// AES-128
	key128, _ := aesgcm.Generate128Key()
	crypto128, _ := aesgcm.NewAESGCM(key128)
	formatted128, _ := crypto128.EncryptToString("AES-128加密数据")

	// AES-256
	key256, _ := aesgcm.Generate256Key()
	crypto256, _ := aesgcm.NewAESGCM(key256)
	formatted256, _ := crypto256.EncryptToString("AES-256加密数据")

	// 解析算法信息
	algo128, _, _ := aesgcm.ParseFormattedString(formatted128)
	algo256, _, _ := aesgcm.ParseFormattedString(formatted256)

	fmt.Printf("AES-128算法: %s\n", algo128)
	fmt.Printf("AES-256算法: %s\n", algo256)

	// 验证解密
	decrypted128, _ := crypto128.DecryptFromString(formatted128)
	decrypted256, _ := crypto256.DecryptFromString(formatted256)

	fmt.Printf("AES-128解密成功: %v\n", decrypted128 == "AES-128加密数据")
	fmt.Printf("AES-256解密成功: %v\n", decrypted256 == "AES-256加密数据")
}
Output:

AES-128算法: AES_128_GCM_V1
AES-256算法: AES_256_GCM_V1
AES-128解密成功: true
AES-256解密成功: true
Example (EncryptToString)

Example_EncryptToString 展示格式化字符串加密

package main

import (
	"fmt"
	"log"
	"strings"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 生成密钥
	key, err := aesgcm.Generate256Key()
	if err != nil {
		log.Fatal(err)
	}

	// 创建加密器
	crypto, err := aesgcm.NewAESGCM(key)
	if err != nil {
		log.Fatal(err)
	}

	// 加密为格式化字符串
	plaintext := "这是一段需要加密的敏感数据"
	formatted, err := crypto.EncryptToString(plaintext)
	if err != nil {
		log.Fatal(err)
	}

	// 只验证格式前缀,不验证具体内容
	if strings.HasPrefix(formatted, "AES_256_GCM_V1:") {
		fmt.Println("格式化加密字符串格式正确")
	}

	// 解密格式化字符串
	decrypted, err := crypto.DecryptFromString(formatted)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("解密成功: %v\n", decrypted == plaintext)
}
Output:

格式化加密字符串格式正确
解密成功: true
Example (EncryptToStringWithMetadata)

Example_EncryptToStringWithMetadata 展示带元数据的格式化字符串加密

package main

import (
	"fmt"
	"log"
	"strings"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	key, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAESGCM(key)

	// 加密为带元数据的格式化字符串
	plaintext := "这是一段需要加密的敏感数据"
	formatted, err := crypto.EncryptToStringWithMetadata(plaintext)
	if err != nil {
		log.Fatal(err)
	}

	// 只验证格式前缀
	if strings.HasPrefix(formatted, "AES_256_GCM_V1:") {
		fmt.Println("带元数据的格式化字符串格式正确")
	}

	// 解密
	decrypted, err := crypto.DecryptFromStringWithMetadata(formatted)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("解密成功: %v\n", decrypted == plaintext)
}
Output:

带元数据的格式化字符串格式正确
解密成功: true
Example (EncryptionWorkflow)

Example_encryptionWorkflow 展示完整的加密工作流程

package main

import (
	"fmt"
	"log"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 步骤1: 生成密钥
	key, err := aesgcm.Generate256Key()
	if err != nil {
		log.Fatal("密钥生成失败:", err)
	}
	fmt.Println("✓ 密钥生成成功")

	// 步骤2: 创建加密器
	crypto, err := aesgcm.NewAESGCM(key)
	if err != nil {
		log.Fatal("加密器创建失败:", err)
	}
	fmt.Println("✓ 加密器创建成功")

	// 步骤3: 加密数据
	plaintext := "Hello, AES-GCM!"
	ciphertext, err := crypto.Encrypt([]byte(plaintext))
	if err != nil {
		log.Fatal("加密失败:", err)
	}
	fmt.Println("✓ 数据加密成功")

	// 步骤4: 解密数据
	decrypted, err := crypto.Decrypt(ciphertext)
	if err != nil {
		log.Fatal("解密失败:", err)
	}
	fmt.Println("✓ 数据解密成功")

	// 步骤5: 验证数据完整性
	if string(decrypted) == plaintext {
		fmt.Println("✓ 数据完整性验证通过")
	} else {
		fmt.Println("✗ 数据完整性验证失败")
	}
}
Output:

✓ 密钥生成成功
✓ 加密器创建成功
✓ 数据加密成功
✓ 数据解密成功
✓ 数据完整性验证通过
Example (ErrorHandling)

Example_errorHandling 展示错误处理

package main

import (
	"fmt"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 测试无效密钥
	_, err := aesgcm.NewAESGCM([]byte("short-key"))
	if err != nil {
		fmt.Println("捕获无效密钥错误")
	}

	// 测试无效密钥长度
	_, err = aesgcm.GenerateKey(aesgcm.KeySize(20))
	if err != nil {
		fmt.Println("捕获无效密钥长度错误")
	}

	// 测试无效密文
	key, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAESGCM(key)
	_, err = crypto.Decrypt([]byte("short"))
	if err != nil {
		fmt.Println("捕获无效密文错误")
	}

	// 测试篡改的密文
	plaintext := "测试数据"
	ciphertext, _ := crypto.Encrypt([]byte(plaintext))

	// 篡改密文
	tampered := make([]byte, len(ciphertext))
	copy(tampered, ciphertext)
	if len(tampered) > 20 {
		tampered[20] ^= 0x01
	}

	_, err = crypto.Decrypt(tampered)
	if err != nil {
		fmt.Println("捕获数据篡改错误")
	}
}
Output:

捕获无效密钥错误
捕获无效密钥长度错误
捕获无效密文错误
捕获数据篡改错误
Example (FormattedStringErrorHandling)

Example_formattedStringErrorHandling 展示格式化字符串的错误处理

package main

import (
	"fmt"
	"strings"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	key, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAESGCM(key)

	// 测试无效格式
	_, err := crypto.DecryptFromString("invalid-format")
	if err != nil {
		fmt.Printf("无效格式错误: %v\n", err)
	}

	// 测试错误的算法
	_, err = crypto.DecryptFromString("WRONG_ALGO:fingerprint:data")
	if err != nil {
		fmt.Printf("错误算法错误: %v\n", err)
	}

	// 测试错误的密钥指纹 - 创建一个有效的格式但使用错误的密钥长度标识
	validFormatted, _ := crypto.EncryptToString("测试数据")
	parts := strings.Split(validFormatted, ":")
	// 修改算法部分为错误的密钥长度
	wrongAlgorithm := "AES_128_GCM_V1"
	wrongFormatted := wrongAlgorithm + ":" + parts[1] + ":" + parts[2]
	_, err = crypto.DecryptFromString(wrongFormatted)
	if err != nil {
		fmt.Printf("密钥长度不匹配错误: %v\n", err)
	}
}
Output:

无效格式错误: invalid formatted string: expected 3 parts
错误算法错误: invalid algorithm format
密钥长度不匹配错误: key size mismatch: expected 256, got AES_128_GCM_V1
Example (FormattedStringUsage)

Example_formattedStringUsage 展示格式化字符串的实际使用场景

package main

import (
	"fmt"
	"strings"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	key, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAESGCM(key)

	// 场景1: 数据库存储
	userData := "用户敏感信息"
	dbFormatted, _ := crypto.EncryptToString(userData)
	// 只验证格式前缀
	if strings.HasPrefix(dbFormatted, "AES_256_GCM_V1:") {
		fmt.Println("数据库存储格式正确")
	}

	// 场景2: 配置文件
	configData := "数据库密码"
	configFormatted, _ := crypto.EncryptToString(configData)
	if strings.HasPrefix(configFormatted, "AES_256_GCM_V1:") {
		fmt.Println("配置文件格式正确")
	}

	// 场景3: API传输
	apiData := "API密钥"
	apiFormatted, _ := crypto.EncryptToString(apiData)
	if strings.HasPrefix(apiFormatted, "AES_256_GCM_V1:") {
		fmt.Println("API传输格式正确")
	}

	// 验证所有数据都能正确解密
	dbDecrypted, _ := crypto.DecryptFromString(dbFormatted)
	configDecrypted, _ := crypto.DecryptFromString(configFormatted)
	apiDecrypted, _ := crypto.DecryptFromString(apiFormatted)

	allSuccess := dbDecrypted == userData &&
		configDecrypted == configData &&
		apiDecrypted == apiData

	fmt.Printf("所有场景加解密验证: %v\n", allSuccess)
}
Output:

数据库存储格式正确
配置文件格式正确
API传输格式正确
所有场景加解密验证: true
Example (KeyFingerprintVerification)

Example_keyFingerprintVerification 展示密钥指纹验证

package main

import (
	"fmt"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 创建两个不同的密钥
	key1, _ := aesgcm.Generate256Key()
	crypto1, _ := aesgcm.NewAESGCM(key1)

	key2, _ := aesgcm.Generate256Key()
	crypto2, _ := aesgcm.NewAESGCM(key2)

	// 使用密钥1加密
	formatted, _ := crypto1.EncryptToString("敏感数据")

	// 验证密钥匹配
	match1 := crypto1.IsEncryptedByMe(formatted)
	match2 := crypto2.IsEncryptedByMe(formatted)

	fmt.Printf("密钥1匹配: %v\n", match1)
	fmt.Printf("密钥2匹配: %v\n", match2)

	// 尝试使用错误密钥解密
	_, err := crypto2.DecryptFromString(formatted)
	if err != nil {
		fmt.Printf("密钥不匹配错误: %v\n", err)
	}
}
Output:

密钥1匹配: true
密钥2匹配: false
密钥不匹配错误: key fingerprint mismatch
Example (KeyManagement)

Example_keyManagement 展示密钥管理

package main

import (
	"fmt"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 生成不同长度的密钥
	key128, _ := aesgcm.GenerateKey(aesgcm.AES128)
	key192, _ := aesgcm.GenerateKey(aesgcm.AES192)
	key256, _ := aesgcm.GenerateKey(aesgcm.AES256)

	fmt.Printf("支持AES-128: %v\n", len(key128) == 16)
	fmt.Printf("支持AES-192: %v\n", len(key192) == 24)
	fmt.Printf("支持AES-256: %v\n", len(key256) == 32)

	// 使用便捷函数
	key256Easy, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAES256GCM(key256Easy)

	plaintext := "测试数据"
	ciphertext, _ := crypto.Encrypt([]byte(plaintext))
	decrypted, _ := crypto.Decrypt(ciphertext)

	fmt.Printf("加解密功能正常: %v\n", string(decrypted) == plaintext)
}
Output:

支持AES-128: true
支持AES-192: true
支持AES-256: true
加解密功能正常: true
Example (NewAESGCMFromBase64)

Example_newAESGCMFromBase64 展示base64密钥的使用示例

package main

import (
	"fmt"
	"log"
	"strings"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 从配置文件读取base64编码的密钥
	keyBase64 := "4pSf+zOOucXZrnnNamN/HFcUy55bwCcw1HmCi5U5S9w="

	// 创建加密器
	crypto, err := aesgcm.NewAESGCMFromBase64(keyBase64)
	if err != nil {
		log.Fatal(err)
	}

	// 获取密钥信息
	keySize, fingerprint := crypto.GetKeyInfo()

	// 验证密钥长度
	if keySize == "256" {
		fmt.Println("密钥长度: 256位")
	}

	// 验证指纹格式(16字符的hex)
	if len(fingerprint) == 16 {
		fmt.Println("密钥指纹格式正确")
	}

	// 加密数据
	plaintext := "敏感数据"
	formatted, err := crypto.EncryptToString(plaintext)
	if err != nil {
		log.Fatal(err)
	}

	// 验证加密字符串格式
	if strings.HasPrefix(formatted, "AES_256_GCM_V1:") && len(formatted) > 30 {
		fmt.Println("加密成功")
	}

	// 解密数据
	decrypted, err := crypto.DecryptFromString(formatted)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("解密成功: %v\n", decrypted == plaintext)
}
Output:

密钥长度: 256位
密钥指纹格式正确
加密成功
解密成功: true
Example (NonceUniqueness)

Example_nonceUniqueness 展示Nonce唯一性的重要性

package main

import (
	"crypto/hmac"
	"encoding/hex"
	"fmt"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	key, _ := aesgcm.GenerateKey(aesgcm.AES256)
	crypto, _ := aesgcm.NewAESGCM(key)

	// 正确用法:每次加密自动生成新的随机nonce
	message1 := "第一条消息"
	message2 := "第二条消息"

	ciphertext1, _ := crypto.Encrypt([]byte(message1))
	ciphertext2, _ := crypto.Encrypt([]byte(message2))

	// 提取nonce进行比较(仅用于演示)
	nonce1 := ciphertext1[:12] // GCM通常使用12字节nonce
	nonce2 := ciphertext2[:12]

	fmt.Printf("Nonce1: %s\n", hex.EncodeToString(nonce1))
	fmt.Printf("Nonce2: %s\n", hex.EncodeToString(nonce2))
	fmt.Printf("Nonce是否唯一: %t\n", !hmac.Equal(nonce1, nonce2))

	// 安全提示
	fmt.Println("安全提示: 永远不要重复使用nonce!")
	fmt.Println("重复使用nonce会严重破坏GCM的安全性")
}
Example (ParseFormattedString)

Example_parseFormattedString 展示解析格式化字符串

package main

import (
	"fmt"
	"log"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	key, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAESGCM(key)

	// 加密数据
	formatted, _ := crypto.EncryptToString("测试数据")

	// 解析格式化字符串
	algorithm, fingerprint, err := aesgcm.ParseFormattedString(formatted)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("算法: %s\n", algorithm)
	// 只验证指纹长度,不验证具体值
	if len(fingerprint) == 16 {
		fmt.Println("密钥指纹长度正确")
	}

	// 验证密钥匹配
	isMatch := crypto.IsEncryptedByMe(formatted)
	fmt.Printf("密钥匹配: %v\n", isMatch)
}
Output:

算法: AES_256_GCM_V1
密钥指纹长度正确
密钥匹配: true
Example (PerformanceConsiderations)

Example_performanceConsiderations 展示性能考虑

package main

import (
	"fmt"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	key, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAESGCM(key)

	// 批量加密
	messages := []string{
		"第一条消息",
		"第二条消息",
		"测试消息",
	}

	successCount := 0
	for _, msg := range messages {
		_, err := crypto.Encrypt([]byte(msg))
		if err != nil {
			continue
		}
		successCount++
	}

	fmt.Printf("成功加密 %d 条消息\n", successCount)
}
Output:

成功加密 3 条消息
Example (SecurityBestPractices)

Example_securityBestPractices 展示安全最佳实践

package main

import (
	"fmt"
	"log"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 1. 使用足够长度的密钥
	key, _ := aesgcm.Generate256Key()

	// 2. 创建加密器
	crypto, _ := aesgcm.NewAESGCM(key)

	// 3. 加密数据
	sensitiveData := "信用卡号: 1234-5678-9012-3456"
	ciphertext, _ := crypto.Encrypt([]byte(sensitiveData))

	// 4. 安全处理解密错误
	_, err := crypto.Decrypt(ciphertext)
	if err != nil {
		log.Printf("安全警告: 数据完整性验证失败 - %v", err)
		return
	}

	fmt.Printf("解密成功\n")
}
Output:

解密成功
Example (StringEncryption)

Example_stringEncryption 展示字符串加密

package main

import (
	"fmt"
	"log"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	key, _ := aesgcm.Generate256Key()
	crypto, _ := aesgcm.NewAESGCM(key)

	// 加密为base64字符串,适合存储到数据库
	userData := "用户私密信息"
	encoded, err := crypto.EncryptToString(userData)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("加密成功\n")

	// 从数据库读取后解密
	decrypted, err := crypto.DecryptFromString(encoded)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("解密成功: %s\n", decrypted)
}
Output:

加密成功
解密成功: 用户私密信息
Example (StringKeyUsage)

Example_stringKeyUsage 专门展示字符串密钥的使用

package main

import (
	"fmt"
	"log"

	aesgcm "github.com/infraboard/mcube/v2/crypto/aes_gcm"
)

func main() {
	// 方法1: 使用字节数组(推荐)- 使用确切的32字节
	keyBytes := []byte("0123456789abcdef0123456789abcdef") // 确切的32字节
	crypto1, err := aesgcm.NewAESGCM(keyBytes)
	if err != nil {
		log.Fatal(err)
	}
	_, err = crypto1.EncryptToString("使用方法1加密的数据")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("字节数组密钥加密成功\n")

	// 方法2: 使用字符串(需要精确长度)
	keyStr := "abcdefghijklmnopqrstuvwxyz123456" // 32字节字符串
	crypto2, err := aesgcm.NewAESGCMFromString(keyStr, aesgcm.AES256)
	if err != nil {
		log.Fatal(err)
	}
	_, err = crypto2.EncryptToString("使用方法2加密的数据")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("字符串密钥加密成功\n")
}
Output:

字节数组密钥加密成功
字符串密钥加密成功

Index

Examples

Constants

View Source
const (
	AlgorithmAESGCM = 0x01
)

加密算法标识

View Source
const (
	FormatVersion1 = 0x01
)

加密格式版本

Variables

View Source
var (
	ErrInvalidKeySize    = errors.New("invalid key size: must be 16, 24, or 32 bytes")
	ErrInvalidCiphertext = errors.New("invalid ciphertext")
	ErrDecryptionFailed  = errors.New("decryption failed: authentication failed")
)

错误定义

Functions

func Generate128Key

func Generate128Key() ([]byte, error)

Generate128Key 生成128位随机密钥 适用于性能敏感但安全性要求稍低的场景

func Generate192Key

func Generate192Key() ([]byte, error)

Generate192Key 生成192位随机密钥 适用于中等安全性要求的场景(不常用)

func Generate256Key

func Generate256Key() ([]byte, error)

Generate256Key 生成256位随机密钥 推荐用于生成高安全性的密钥

func GenerateKey

func GenerateKey(keySize KeySize) ([]byte, error)

GenerateKey 生成指定长度的随机密钥 适用于密钥生成场景,使用枚举类型确保密钥长度正确

func MustGenerateKey

func MustGenerateKey(keySize KeySize) []byte

func ParseFormattedString

func ParseFormattedString(formatted string) (algorithm, keyFingerprint string, err error)

辅助函数:从格式化字符串中提取信息

Types

type AESGCM

type AESGCM struct {
	// contains filtered or unexported fields
}

AESGCM 封装AES-GCM加密解密功能

func NewAES256GCM

func NewAES256GCM(key []byte) (*AESGCM, error)

NewAES256GCM 创建使用256位密钥的AESGCM实例 推荐用于大多数生产环境,提供最高级别的安全性

func NewAESGCM

func NewAESGCM(key []byte) (*AESGCM, error)

NewAESGCM 创建一个新的AESGCM实例 适用于需要灵活指定任意有效密钥长度的场景

func NewAESGCMFromBase64

func NewAESGCMFromBase64(keyBase64 string) (*AESGCM, error)

NewAESGCMFromBase64 从base64字符串创建AESGCM实例 适用于从配置文件读取base64编码密钥的场景

func NewAESGCMFromString

func NewAESGCMFromString(key string, keySize KeySize) (*AESGCM, error)

NewAESGCMFromString 从字符串创建AESGCM实例 适用于从配置文件或环境变量中读取密钥的场景 注意:字符串形式的密钥安全性较低,建议使用字节数组密钥

func (*AESGCM) Decrypt

func (a *AESGCM) Decrypt(ciphertext []byte) ([]byte, error)

Decrypt 解密密文数据 基础解密方法,对应Encrypt方法的输出 输入格式: nonce + ciphertext + tag

func (*AESGCM) DecryptFromString

func (a *AESGCM) DecryptFromString(formatted string) (string, error)

对应EncryptToString方法的输出 适用于从字符串格式恢复加密数据的场景 DecryptFromString 从格式化字符串解密

func (*AESGCM) DecryptFromStringWithMetadata

func (a *AESGCM) DecryptFromStringWithMetadata(formatted string) (string, error)

DecryptFromStringWithMetadata 从包含完整元数据的格式化字符串解密

func (*AESGCM) DecryptWithAdditionalData

func (a *AESGCM) DecryptWithAdditionalData(ciphertext, additionalData []byte) ([]byte, error)

DecryptWithAdditionalData 使用附加数据进行解密 对应EncryptWithAdditionalData方法的输出 必须提供与加密时相同的附加数据,否则认证会失败

func (*AESGCM) Encrypt

func (a *AESGCM) Encrypt(plaintext []byte) ([]byte, error)

Encrypt 加密明文数据 基础加密方法,适用于大多数简单的加密场景,不涉及额外的认证数据 返回格式: nonce + ciphertext + tag

func (*AESGCM) EncryptToString

func (a *AESGCM) EncryptToString(plaintext string) (string, error)

适用于需要将加密结果存储为字符串的场景,如: - 数据库存储 - JSON/XML序列化 - URL参数传递 返回的字符串可以直接存储或传输 EncryptToString 加密并返回格式化的字符串 格式: AES_{key_size}_GCM_V{version}:{key_fingerprint}:{base64_data} 示例: AES_256_GCM_V1:a1b2c3d4e5f6g7h8:Base64EncodedData...

func (*AESGCM) EncryptToStringWithMetadata

func (a *AESGCM) EncryptToStringWithMetadata(plaintext string) (string, error)

EncryptToStringWithMetadata 加密并返回包含完整元数据的格式化字符串 格式: AES_{key_size}_GCM_V{version}:{key_fingerprint}:{base64_metadata}:{base64_ciphertext} 元数据包含: [版本1字节][算法1字节][密钥指纹8字节][nonce12字节]

func (*AESGCM) EncryptWithAdditionalData

func (a *AESGCM) EncryptWithAdditionalData(plaintext, additionalData []byte) ([]byte, error)

EncryptWithAdditionalData 使用附加数据进行加密 适用于需要同时加密和认证额外数据的场景,如: - 加密消息头信息 - 保护关联的元数据 - 需要额外上下文认证的场景 附加数据本身不会被加密,但会参与认证标签的计算

func (*AESGCM) GetKeyFingerprint

func (a *AESGCM) GetKeyFingerprint() string

GetKeyFingerprint 获取密钥指纹

func (*AESGCM) GetKeyFingerprintFull

func (a *AESGCM) GetKeyFingerprintFull() string

GetKeyFingerprintFull 获取完整密钥指纹

func (*AESGCM) GetKeyInfo

func (a *AESGCM) GetKeyInfo() (keySize string, fingerprint string)

GetKeyInfo 获取当前密钥的信息

func (*AESGCM) GetKeyInfoDetailed

func (a *AESGCM) GetKeyInfoDetailed() map[string]any

GetKeyInfoDetailed 获取更详细的密钥信息

func (*AESGCM) GetKeySize

func (a *AESGCM) GetKeySize() int

GetKeySize 获取密钥大小

func (*AESGCM) GetKeySizeBits

func (a *AESGCM) GetKeySizeBits() int

GetKeySizeBits 获取密钥位数

func (*AESGCM) IsEncryptedByMe

func (a *AESGCM) IsEncryptedByMe(formatted string) bool

辅助函数:验证格式化字符串是否由当前密钥加密

func (*AESGCM) ValidateKey

func (a *AESGCM) ValidateKey() error

ValidateKey 验证密钥是否有效

type KeySize

type KeySize int

KeySize 定义密钥大小的枚举类型

const (
	AES128 KeySize = 16 // AES-128: 安全性足够,性能最佳
	AES192 KeySize = 24 // AES-192: 中等安全性,不常用
	AES256 KeySize = 32 // AES-256: 最高安全性,推荐用于敏感数据
)

func (KeySize) String

func (k KeySize) String() string

String 返回密钥大小的字符串表示

func (KeySize) Valid

func (k KeySize) Valid() bool

Valid 检查密钥大小是否有效

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL