Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Go 语言标准库 —— crypto/des 包(DES 加密)


🔹 概述

crypto/des 包实现了数据加密标准(DES)和三重数据加密算法(TDEA/Triple DES)。

主要功能:

  • DES(Data Encryption Standard)加密算法
  • 3DES(Triple DES)加密算法
  • 符合 FIPS 46-3 标准

⚠️ 重要安全警告:

  • DES 已被破解,不应再用于安全应用
  • ⚠️ 3DES 也已过时,建议使用 AES
  • 🔒 仅用于兼容旧系统或学习目的
  • 🚫 不推荐用于新系统

重要说明:

  • DES 是分组密码(Block Cipher)
  • DES 分组大小:64 位(8 字节)
  • DES 密钥长度:64 位(8 字节,其中 56 位有效 + 8 位奇偶校验)
  • 3DES 密钥长度:192 位(24 字节)
  • 需要配合工作模式使用(CBC、CTR 等)

🔹 常量

BlockSize

const BlockSize = 8
  • 说明:
    • DES 的分组大小(字节数)
    • 固定为 8 字节(64 位)
  • 使用场景:
    • 确定数据块大小
    • 计算填充大小

🔹 核心函数

创建 DES Cipher

des.NewCipher(key []byte) (cipher.Block, error)

  • 说明:

    • 创建新的 DES cipher 实例
    • 实现 DES 加密算法
  • 参数:

    • key []byte - 密钥(必须是 8 字节)
  • 返回值:

    • cipher.Block - DES cipher 接口
    • error - 错误信息
  • 错误情况:

    • 密钥长度不是 8 字节
    • 密钥是弱密钥(weak key)
  • 示例:

    package main
    
    import (
    	"crypto/cipher"
    	"crypto/des"
    	"fmt"
    )
    
    func main() {
    	// 创建 DES cipher(8 字节密钥)
    	key := []byte("12345678") // 8 字节
    	block, err := des.NewCipher(key)
    	if err != nil {
    		fmt.Println("错误:", err)
    		return
    	}
    	
    	// 获取分组大小
    	fmt.Printf("DES 分组大小:%d 字节\n", block.BlockSize())
    	fmt.Printf("DES 创建成功\n")
    	
    	// 使用 cipher(配合工作模式)
    	_ = cipher.NewCBCEncrypter(block, make([]byte, 8))
    }
    
  • 注意事项:

    • ⚠️ DES 密钥长度必须是 8 字节
    • ⚠️ DES 已被证明不安全
    • ⚠️ 存在弱密钥(weak keys)

创建 3DES Cipher

des.NewTripleDESCipher(key []byte) (cipher.Block, error)

  • 说明:

    • 创建新的 Triple DES cipher 实例
    • 实现 TDEA(Triple Data Encryption Algorithm)
    • 比 DES 更安全,但已过时
  • 参数:

    • key []byte - 密钥(必须是 24 字节)
  • 返回值:

    • cipher.Block - 3DES cipher 接口
    • error - 错误信息
  • 错误情况:

    • 密钥长度不是 24 字节
  • 示例:

    package main
    
    import (
    	"crypto/cipher"
    	"crypto/des"
    	"fmt"
    )
    
    func main() {
    	// 创建 3DES cipher(24 字节密钥)
    	key := []byte("123456789012345678901234") // 24 字节
    	block, err := des.NewTripleDESCipher(key)
    	if err != nil {
    		fmt.Println("错误:", err)
    		return
    	}
    	
    	// 获取分组大小(仍然是 8 字节)
    	fmt.Printf("3DES 分组大小:%d 字节\n", block.BlockSize())
    	fmt.Printf("3DES 创建成功\n")
    	
    	// 使用 cipher(配合工作模式)
    	_ = cipher.NewCBCEncrypter(block, make([]byte, 8))
    }
    
  • 注意事项:

    • ⚠️ 3DES 密钥长度必须是 24 字节
    • ⚠️ 3DES 比 DES 安全,但性能较差
    • ⚠️ 已逐渐被 AES 取代

🔹 错误类型

KeySizeError

type KeySizeError int
  • 说明:

    • 密钥大小错误类型
    • 当密钥长度不正确时返回
  • 方法:

    • Error() string - 返回错误信息
  • 示例:

    package main
    
    import (
    	"crypto/des"
    	"fmt"
    )
    
    func main() {
    	// 错误的密钥长度
    	key := []byte("short") // 只有 5 字节
    	_, err := des.NewCipher(key)
    	if err != nil {
    		fmt.Printf("错误类型:%T\n", err)
    		fmt.Printf("错误信息:%s\n", err.Error())
    	}
    }
    

🔹 工作模式示例

DES-CBC 加密

package main

import (
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
)

// PKCS5 填充(DES 使用)
func pkcs5Pad(data []byte, blockSize int) []byte {
	padding := blockSize - len(data)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padtext...)
}

// PKCS5 去填充
func pkcs5Unpad(data []byte) ([]byte, error) {
	if len(data) == 0 {
		return nil, fmt.Errorf("数据为空")
	}
	padding := int(data[len(data)-1])
	if padding > len(data) || padding == 0 {
		return nil, fmt.Errorf("无效的填充")
	}
	for i := 0; i < padding; i++ {
		if data[len(data)-1-i] != byte(padding) {
			return nil, fmt.Errorf("无效的填充")
		}
	}
	return data[:len(data)-padding], nil
}

// DES-CBC 加密
func encryptDESCBC(plaintext []byte, key []byte) ([]byte, error) {
	block, err := des.NewCipher(key)
	if err != nil {
		return nil, err
	}
	
	// PKCS5 填充
	plaintext = pkcs5Pad(plaintext, block.BlockSize())
	
	// 生成随机 IV(8 字节)
	ciphertext := make([]byte, des.BlockSize+len(plaintext))
	iv := ciphertext[:des.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return nil, err
	}
	
	// CBC 加密
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext[des.BlockSize:], plaintext)
	
	return ciphertext, nil
}

// DES-CBC 解密
func decryptDESCBC(ciphertext []byte, key []byte) ([]byte, error) {
	block, err := des.NewCipher(key)
	if err != nil {
		return nil, err
	}
	
	if len(ciphertext) < des.BlockSize {
		return nil, fmt.Errorf("密文太短")
	}
	
	// 分离 IV 和密文
	iv := ciphertext[:des.BlockSize]
	ciphertext = ciphertext[des.BlockSize:]
	
	// CBC 解密
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(ciphertext, ciphertext)
	
	// 去填充
	plaintext, err := pkcs5Unpad(ciphertext)
	return plaintext, err
}

func main() {
	key := []byte("12345678") // 8 字节 DES 密钥
	plaintext := []byte("Hello, DES!")
	
	ciphertext, err := encryptDESCBC(plaintext, key)
	if err != nil {
		fmt.Println("加密失败:", err)
		return
	}
	fmt.Printf("密文:%s\n", hex.EncodeToString(ciphertext))
	
	decrypted, err := decryptDESCBC(ciphertext, key)
	if err != nil {
		fmt.Println("解密失败:", err)
		return
	}
	fmt.Printf("明文:%s\n", string(decrypted))
}

3DES-CBC 加密

package main

import (
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
)

// 3DES-CBC 加密
func encrypt3DESCBC(plaintext []byte, key []byte) ([]byte, error) {
	block, err := des.NewTripleDESCipher(key)
	if err != nil {
		return nil, err
	}
	
	// PKCS5 填充
	plaintext = pkcs5Pad(plaintext, block.BlockSize())
	
	// 生成随机 IV(8 字节)
	ciphertext := make([]byte, des.BlockSize+len(plaintext))
	iv := ciphertext[:des.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return nil, err
	}
	
	// CBC 加密
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext[des.BlockSize:], plaintext)
	
	return ciphertext, nil
}

// 3DES-CBC 解密
func decrypt3DESCBC(ciphertext []byte, key []byte) ([]byte, error) {
	block, err := des.NewTripleDESCipher(key)
	if err != nil {
		return nil, err
	}
	
	if len(ciphertext) < des.BlockSize {
		return nil, fmt.Errorf("密文太短")
	}
	
	// 分离 IV 和密文
	iv := ciphertext[:des.BlockSize]
	ciphertext = ciphertext[des.BlockSize:]
	
	// CBC 解密
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(ciphertext, ciphertext)
	
	// 去填充
	plaintext, err := pkcs5Unpad(ciphertext)
	return plaintext, err
}

func main() {
	key := []byte("123456789012345678901234") // 24 字节 3DES 密钥
	plaintext := []byte("Hello, 3DES!")
	
	ciphertext, _ := encrypt3DESCBC(plaintext, key)
	fmt.Printf("密文:%s\n", hex.EncodeToString(ciphertext))
	
	decrypted, _ := decrypt3DESCBC(ciphertext, key)
	fmt.Printf("明文:%s\n", string(decrypted))
}

DES-CTR 模式

package main

import (
	"crypto/cipher"
	"crypto/des"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
)

// DES-CTR 加密/解密(相同操作)
func encryptDESCTR(plaintext []byte, key []byte) ([]byte, error) {
	block, err := des.NewCipher(key)
	if err != nil {
		return nil, err
	}
	
	// 生成随机 nonce(8 字节)
	ciphertext := make([]byte, des.BlockSize+len(plaintext))
	nonce := ciphertext[:des.BlockSize]
	if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
		return nil, err
	}
	
	// CTR 模式
	stream := cipher.NewCTR(block, nonce)
	stream.XORKeyStream(ciphertext[des.BlockSize:], plaintext)
	
	return ciphertext, nil
}

// DES-CTR 解密
func decryptDESCTR(ciphertext []byte, key []byte) ([]byte, error) {
	block, err := des.NewCipher(key)
	if err != nil {
		return nil, err
	}
	
	if len(ciphertext) < des.BlockSize {
		return nil, fmt.Errorf("密文太短")
	}
	
	// 分离 nonce 和密文
	nonce := ciphertext[:des.BlockSize]
	ciphertext = ciphertext[des.BlockSize:]
	
	// CTR 模式(解密相同)
	stream := cipher.NewCTR(block, nonce)
	plaintext := make([]byte, len(ciphertext))
	stream.XORKeyStream(plaintext, ciphertext)
	
	return plaintext, nil
}

func main() {
	key := []byte("12345678")
	plaintext := []byte("Hello, DES-CTR!")
	
	ciphertext, _ := encryptDESCTR(plaintext, key)
	fmt.Printf("密文:%s\n", hex.EncodeToString(ciphertext))
	
	decrypted, _ := decryptDESCTR(ciphertext, key)
	fmt.Printf("明文:%s\n", string(decrypted))
}

3DES-GCM 模式(推荐用于 3DES)

package main

import (
	"crypto/cipher"
	"crypto/des"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
)

// 3DES-GCM 加密
func encrypt3DESGCM(plaintext []byte, key []byte) ([]byte, error) {
	block, err := des.NewTripleDESCipher(key)
	if err != nil {
		return nil, err
	}
	
	// 创建 GCM
	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return nil, err
	}
	
	// 生成随机 nonce
	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
}

// 3DES-GCM 解密
func decrypt3DESGCM(ciphertext []byte, key []byte) ([]byte, error) {
	block, err := des.NewTripleDESCipher(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("密文太短")
	}
	
	// 分离 nonce 和密文
	nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
	
	// 解密并验证
	plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
	return plaintext, err
}

func main() {
	key := []byte("123456789012345678901234")
	plaintext := []byte("Hello, 3DES-GCM!")
	
	ciphertext, _ := encrypt3DESGCM(plaintext, key)
	fmt.Printf("密文:%s\n", hex.EncodeToString(ciphertext))
	
	decrypted, _ := decrypt3DESGCM(ciphertext, key)
	fmt.Printf("明文:%s\n", string(decrypted))
}

🔹 使用场景

1. 兼容旧系统加密

package main

import (
	"crypto/cipher"
	"crypto/des"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
)

// 加密(用于兼容旧系统)
func encryptLegacy(data []byte, key []byte) ([]byte, error) {
	block, err := des.NewCipher(key)
	if err != nil {
		return nil, err
	}
	
	ciphertext := make([]byte, des.BlockSize+len(data))
	iv := ciphertext[:des.BlockSize]
	io.ReadFull(rand.Reader, iv)
	
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext[des.BlockSize:], data)
	
	return ciphertext, nil
}

// 解密(用于兼容旧系统)
func decryptLegacy(ciphertext []byte, key []byte) ([]byte, error) {
	block, err := des.NewCipher(key)
	if err != nil {
		return nil, err
	}
	
	iv := ciphertext[:des.BlockSize]
	ciphertext = ciphertext[des.BlockSize:]
	
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(ciphertext, ciphertext)
	
	return ciphertext, nil
}

func main() {
	// 场景:与使用 DES 的旧系统通信
	key := []byte("legacy88")
	data := []byte("Legacy system data")
	
	encrypted, _ := encryptLegacy(data, key)
	fmt.Printf("加密(兼容旧系统):%s\n", hex.EncodeToString(encrypted))
	
	decrypted, _ := decryptLegacy(encrypted, key)
	fmt.Printf("解密:%s\n", string(decrypted))
}

2. 3DES 加密配置文件

package main

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

type ConfigEncryptor struct {
	key []byte
}

func NewConfigEncryptor(key string) *ConfigEncryptor {
	// 确保密钥是 24 字节
	keyBytes := []byte(key)
	if len(keyBytes) < 24 {
		// 填充密钥
		padded := make([]byte, 24)
		copy(padded, keyBytes)
		keyBytes = padded
	}
	return &ConfigEncryptor{key: keyBytes[:24]}
}

func (e *ConfigEncryptor) Encrypt(configData []byte) (string, error) {
	block, err := des.NewTripleDESCipher(e.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, configData, nil)
	return base64.StdEncoding.EncodeToString(ciphertext), nil
}

func (e *ConfigEncryptor) Decrypt(encoded string) ([]byte, error) {
	ciphertext, err := base64.StdEncoding.DecodeString(encoded)
	if err != nil {
		return nil, err
	}
	
	block, err := des.NewTripleDESCipher(e.key)
	if err != nil {
		return nil, err
	}
	
	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return nil, err
	}
	
	nonceSize := gcm.NonceSize()
	nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
	
	return gcm.Open(nil, nonce, ciphertext, nil)
}

func main() {
	encryptor := NewConfigEncryptor("mySecretKey123")
	
	// 加密配置
	config := []byte(`{"password": "secret123", "host": "localhost"}`)
	encrypted, _ := encryptor.Encrypt(config)
	fmt.Printf("加密配置:%s\n", encrypted)
	
	// 保存到文件
	os.WriteFile("config.enc", []byte(encrypted), 0600)
	
	// 读取并解密
	encryptedData, _ := os.ReadFile("config.enc")
	decrypted, _ := encryptor.Decrypt(string(encryptedData))
	fmt.Printf("解密配置:%s\n", string(decrypted))
}

3. DES 与 AES 对比测试

package main

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

// DES 加密
func encryptDES(data []byte, key []byte) ([]byte, error) {
	block, _ := des.NewCipher(key)
	ciphertext := make([]byte, des.BlockSize+len(data))
	iv := ciphertext[:des.BlockSize]
	io.ReadFull(rand.Reader, iv)
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext[des.BlockSize:], data)
	return ciphertext, nil
}

// AES 加密
func encryptAES(data []byte, key []byte) ([]byte, error) {
	block, _ := aes.NewCipher(key)
	gcm, _ := cipher.NewGCM(block)
	nonce := make([]byte, gcm.NonceSize())
	io.ReadFull(rand.Reader, nonce)
	ciphertext := gcm.Seal(nonce, nonce, data, nil)
	return ciphertext, nil
}

func main() {
	data := []byte("Test data for comparison")
	desKey := []byte("12345678")
	aesKey := []byte("12345678901234567890123456789012")
	
	fmt.Println("=== DES vs AES 对比 ===")
	
	// DES
	desEnc, _ := encryptDES(data, desKey)
	fmt.Printf("DES 密文长度:%d 字节\n", len(desEnc))
	
	// AES
	aesEnc, _ := encryptAES(data, aesKey)
	fmt.Printf("AES 密文长度:%d 字节\n", len(aesEnc))
	
	fmt.Println("\n结论:")
	fmt.Println("- DES 密钥短(8 字节),但安全性低")
	fmt.Println("- AES 密钥长(32 字节),安全性高")
	fmt.Println("- AES 性能更好,推荐使用 AES")
}

🔹 注意事项和最佳实践

1. 安全警告

  • DES 已被破解

    • 56 位密钥空间太小
    • 可在数小时内暴力破解
    • 不应再用于安全应用
  • ⚠️ 3DES 已过时

    • 虽然比 DES 安全
    • 但性能差,密钥长度不足
    • NIST 已宣布 3DES 将于 2023 年后弃用
  • 推荐使用 AES

    • AES-128/192/256
    • 更安全,性能更好
    • 现代标准
// ❌ 不推荐 - DES
block, _ := des.NewCipher(key) // 不安全

// ⚠️ 仅用于兼容 - 3DES
block, _ := des.NewTripleDESCipher(key) // 已过时

// ✅ 推荐 - AES
block, _ := aes.NewCipher(key) // 安全

2. 密钥管理

  • ⚠️ DES 密钥必须是 8 字节
  • ⚠️ 3DES 密钥必须是 24 字节
  • ✅ 使用随机密钥
  • ✅ 安全存储密钥
// DES 密钥(8 字节)
desKey := []byte("12345678")

// 3DES 密钥(24 字节)
tdesKey := []byte("123456789012345678901234")

// 生成随机密钥
func generateDESKey() ([]byte, error) {
	key := make([]byte, 8)
	_, err := io.ReadFull(rand.Reader, key)
	return key, err
}

func generate3DESKey() ([]byte, error) {
	key := make([]byte, 24)
	_, err := io.ReadFull(rand.Reader, key)
	return key, err
}

3. 弱密钥问题

  • ⚠️ DES 存在弱密钥(weak keys)
  • ⚠️ 某些密钥会产生不安全的加密
  • ✅ 3DES 减少了弱密钥风险
// DES 弱密钥示例(不应使用)
weakKeys := [][]byte{
	[]byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
	[]byte{0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE},
	// ... 更多弱密钥
}

// 检查弱密钥(简化示例)
func isWeakKey(key []byte) bool {
	// 实际实现应检查所有弱密钥
	// 这里仅作示例
	return false
}

4. 填充处理

  • ⚠️ DES/3DES 需要手动填充
  • ✅ 使用 PKCS5/PKCS7 填充
  • ⚠️ 验证填充的正确性
// PKCS5 填充(DES 分组大小为 8)
func pkcs5Pad(data []byte) []byte {
	padding := 8 - len(data)%8
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padtext...)
}

// 去填充
func pkcs5Unpad(data []byte) ([]byte, error) {
	if len(data) == 0 {
		return nil, fmt.Errorf("数据为空")
	}
	padding := int(data[len(data)-1])
	if padding > len(data) || padding == 0 {
		return nil, fmt.Errorf("无效的填充")
	}
	for i := 0; i < padding; i++ {
		if data[len(data)-1-i] != byte(padding) {
			return nil, fmt.Errorf("无效的填充")
		}
	}
	return data[:len(data)-padding], nil
}

5. 模式选择

  • ✅ 优先使用 GCM 模式(认证加密)
  • ✅ CTR 模式用于流式加密
  • ⚠️ CBC 模式需要额外 HMAC
  • ❌ 避免使用 ECB 模式
// 推荐 - GCM
gcm, _ := cipher.NewGCM(block)
ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)

// 流式 - CTR
stream := cipher.NewCTR(block, nonce)
stream.XORKeyStream(ciphertext, plaintext)

// 不推荐 - ECB
// ECB 会暴露数据模式

6. 迁移到 AES

// 旧代码(DES)
func encryptOld(data, key []byte) ([]byte, error) {
	block, _ := des.NewCipher(key)
	// ... DES 加密
}

// 新代码(AES)
func encryptNew(data, key []byte) ([]byte, error) {
	block, _ := aes.NewCipher(key)
	gcm, _ := cipher.NewGCM(block)
	// ... AES-GCM 加密
}

// 迁移策略:
// 1. 评估现有 DES/3DES 使用场景
// 2. 优先替换安全关键场景
// 3. 保持向后兼容性
// 4. 逐步淘汰 DES/3DES

🔥 总结

核心函数

函数说明密钥长度推荐度
des.NewCipher()创建 DES cipher8 字节❌ 不安全
des.NewTripleDESCipher()创建 3DES cipher24 字节⚠️ 过时

算法对比

算法密钥长度分组大小安全性性能状态
DES56 位(8 字节)64 位❌ 已破解已弃用
3DES168 位(24 字节)64 位⚠️ 过时将弃用
AES-128128 位(16 字节)128 位✅ 高很快推荐
AES-256256 位(32 字节)128 位✅ 极高强烈推荐

主要特点

  • 分组密码 👉 固定 64 位(8 字节)分组
  • 对称加密 👉 加密解密使用相同密钥
  • 软件实现 👉 无硬件加速
  • 需要工作模式 👉 CBC、CTR、GCM 等
  • 兼容性好 👉 支持旧系统

使用场景

  • 兼容旧系统 👉 DES/3DES + CBC
  • 配置文件加密 👉 3DES + GCM
  • 学习目的 👉 理解加密原理
  • 迁移过渡 👉 从 DES 迁移到 AES

最佳实践

  • ❌ 不要在新系统中使用 DES
  • ⚠️ 避免使用 3DES,除非必要
  • ✅ 优先使用 AES-256-GCM
  • ✅ 使用随机 IV/Nonce
  • ✅ 不要重复使用 IV/Nonce
  • ✅ 验证解密结果
  • ✅ 安全存储和管理密钥

安全建议

  • 🔒 立即停止使用 DES

    • DES 可在数小时内破解
    • 不应再用于任何安全应用
  • 🔒 逐步淘汰 3DES

    • NIST 已宣布弃用
    • 迁移到 AES
  • 🔒 推荐使用 AES

    • AES-256-GCM
    • 更安全,性能更好
  • 🔒 密钥管理

    • 使用密钥管理服务(KMS)
    • 定期轮换密钥
    • 安全存储密钥

🔹 迁移指南

从 DES 迁移到 AES

package main

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

// 旧 DES 加密
func encryptDES(plaintext []byte, key []byte) (string, error) {
	block, err := des.NewCipher(key)
	if err != nil {
		return "", err
	}
	
	ciphertext := make([]byte, des.BlockSize+len(plaintext))
	iv := ciphertext[:des.BlockSize]
	io.ReadFull(rand.Reader, iv)
	
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext[des.BlockSize:], plaintext)
	
	return base64.StdEncoding.EncodeToString(ciphertext), nil
}

// 新 AES 加密
func encryptAES(plaintext []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())
	io.ReadFull(rand.Reader, nonce)
	
	ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)
	return base64.StdEncoding.EncodeToString(ciphertext), nil
}

func main() {
	data := []byte("Sensitive data")
	
	// 旧 DES
	desKey := []byte("oldkey88")
	oldEncrypted, _ := encryptDES(data, desKey)
	fmt.Printf("DES 加密:%s\n", oldEncrypted)
	
	// 新 AES
	aesKey := []byte("newSecureKey12345678901234567") // 32 字节
	newEncrypted, _ := encryptAES(data, aesKey)
	fmt.Printf("AES 加密:%s\n", newEncrypted)
	
	fmt.Println("\n建议:尽快从 DES 迁移到 AES!")
}

⚠️ crypto/des 包仅用于兼容旧系统或学习目的,新系统应使用 crypto/aes 包!