Go 语言加密与解密之 AES 最佳实践

上篇文章分享了 RSA 加密与解密,咱们这篇文章分享下 AES 解密与解密。

AES(Advanced Encryption Standard)是目前最常用的对称加密算法之一,在数据传输和存储中提供了强大的安全保障。

AES 是一种对称加密算法,这意味着加密和解密都使用同一个密钥。

Go 语言提供了强大的 crypto/aescrypto/cipher 包,使得 AES 加密和解密变得相对容易。

一起来往下看。

一、AES 加密算法基础

1. 对称加密

AES 是一种对称加密算法。对称加密算法的特点是:加密和解密使用相同的密钥,适用于大数据量的加密操作。

AES 支持多种密钥长度:128、192、256 位,其中 256 位提供了最高的安全性。

2. 分组加密模式

AES 是一种分组加密算法,每次加密固定大小(128 位,16 字节)的数据块。

为了加密超过 16 字节的数据,需要使用分组加密模式。

常见的 AES 分组模式包括:

  • ECB(Electronic Codebook):不推荐使用,因为相同的明文块总是产生相同的密文块,容易被攻击。

  • CBC(Cipher Block Chaining):每个明文块在加密前会与前一个密文块进行 XOR 操作,需要一个初始向量(IV)。

  • CFB(Cipher Feedback):将块密码变成一个自同步流密码,不需要填充数据。

  • GCM(Galois/Counter Mode):一种高效且安全的分组模式,提供了数据加密和认证。

3. 填充模式

AES 加密时,数据块必须是 16 字节的倍数,因此需要对不满 16 字节的数据进行填充。

常用的填充方式是 PKCS7,它将缺少的字节填充为等于缺少字节数的值,例如,缺少 4 字节就填充 0x04 四次。

二、在 Go 中实现 AES 加密与解密

我们将使用 AES-256-CBC 模式进行加密和解密,并使用 PKCS7 填充未满 16 字节的数据。

下面是实现 AES 加密和解密的完整代码:

三、AES 加密与解密的实现

1. AES 加密方法
package main

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

// PKCS7 填充
func pkcs7Padding(data []byte, blockSize int) []byte {
 padding := blockSize - len(data)%blockSize
 padText := bytes.Repeat([]byte{byte(padding)}, padding)
 return append(data, padText...)
}

// AES CBC 模式加密
func aesEncrypt(plainText, key []byte) (string, error) {
 // 生成 AES 块
 block, err := aes.NewCipher(key)
 if err != nil {
  return "", err
 }

 // PKCS7 填充
 plainText = pkcs7Padding(plainText, block.BlockSize())

 // 生成随机 IV
 cipherText := make([]byte, aes.BlockSize+len(plainText))
 iv := cipherText[:aes.BlockSize]
 if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  return "", err
 }

 // CBC 加密
 mode := cipher.NewCBCEncrypter(block, iv)
 mode.CryptBlocks(cipherText[aes.BlockSize:], plainText)

 // 返回 base64 编码后的密文
 return base64.StdEncoding.EncodeToString(cipherText), nil
}
2. AES 解密方法
// PKCS7 去除填充
func pkcs7Unpadding(data []byte) ([]byte, error) {
 length := len(data)
 if length == 0 {
  return nil, fmt.Errorf("data length is zero")
 }

 padding := int(data[length-1])
 if padding > length || padding > aes.BlockSize {
  return nil, fmt.Errorf("invalid padding size")
 }

 return data[:length-padding], nil
}

// AES CBC 模式解密
func aesDecrypt(cipherTextBase64 string, key []byte) (string, error) {
 // 解码 base64 密文
 cipherText, err := base64.StdEncoding.DecodeString(cipherTextBase64)
 if err != nil {
  return "", err
 }

 // 生成 AES 块
 block, err := aes.NewCipher(key)
 if err != nil {
  return "", err
 }

 if len(cipherText) < aes.BlockSize {
  return "", fmt.Errorf("cipherText too short")
 }

 // 读取 IV
 iv := cipherText[:aes.BlockSize]
 cipherText = cipherText[aes.BlockSize:]

 // CBC 解密
 mode := cipher.NewCBCDecrypter(block, iv)
 mode.CryptBlocks(cipherText, cipherText)

 // 去除 PKCS7 填充
 plainText, err := pkcs7Unpadding(cipherText)
 if err != nil {
  return "", err
 }

 return string(plainText), nil
}

3. 测试加密和解密

下面是使用以上加解密方法的示例代码:

func main() {
 key := []byte("0123456789abcdef0123456789abcdef") // 32 字节的密钥用于 AES-256
 plainText := "Hello, AES encryption!"

 // 加密
 cipherText, err := aesEncrypt([]byte(plainText), key)
 if err != nil {
  fmt.Println("Encryption failed:", err)
  return
 }
 fmt.Println("Encrypted:", cipherText)

 // 解密
 decryptedText, err := aesDecrypt(cipherText, key)
 if err != nil {
  fmt.Println("Decryption failed:", err)
  return
 }
 fmt.Println("Decrypted:", decryptedText)
}

四、最佳实践

  1. 密钥管理:密钥是 AES 加密的核心,必须确保其安全存储和传输。使用密钥管理服务(如 AWS KMS、HashiCorp Vault)存储密钥,不要将密钥硬编码在代码中。

  2. 选择合适的分组模式:AES 提供多种加密模式,尽量避免使用 ECB 模式,因为它对相同的明文总是生成相同的密文,容易被攻击。建议使用 CBC、GCM 等模式。GCM(Galois/Counter Mode)具有更高的安全性和性能,并支持数据认证。

  3. 使用随机 IV:加密时,为每次加密操作生成一个随机的初始向量(IV),并将 IV 与密文一起传输。IV 不需要保密,但必须确保每次加密时都是随机的,以防止模式攻击。

  4. 处理填充和未填充:AES 加密需要数据块是 16 字节的倍数,因此需要使用 PKCS7 等填充方式。解密时,要谨慎处理填充的去除,以避免解密错误和潜在的攻击。

  5. 错误处理:在加密和解密过程中,密钥长度、IV 长度和数据块大小等操作都可能出错,必须在每个步骤处理这些错误,防止出现潜在的安全漏洞。

  6. 数据完整性:AES 本身只提供加密,不能确保数据完整性。为了防止密文篡改,建议在加密过程中结合 HMAC 或使用 AES-GCM 模式,这些模式可以提供加密和数据完整性验证。

五、最后

咱们已经了解了,如何使用 Go 实现 AES 加密和解密,包括 CBC 模式和 PKCS7 填充。

通过对密钥管理、加密模式选择、IV 随机化、填充处理等方面的最佳实践,确保了 AES 加密的安全性。

AES 是一种高效且强大的对称加密算法,但要在实际应用中确保其安全性,需要谨慎地遵循加密的安全规范。

最后,谢谢你看到了这里👏 想要第一时间接收到推送,可以点个关注。

可点击下方👇 关注公众号

添加作者微信 👇 获取原创学习资料

bc5e6e0728d5689829eb3014081bf70b.jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值