Bootstrap

golang 使用AES加密

在使用AES加密数据后,将加密结果使用base64.StdEncoding.EncodeToString处理的原因是多方面的:

  1. 可读性:AES加密后的数据通常是二进制格式,直接查看或处理这些二进制数据不方便也不直观。Base64编码将这些二进制数据转换为ASCII字符,更易于在各种文本编辑器或系统中查看和传输。

  2. 兼容性:二进制数据直接存储或传输时可能会遇到问题,因为某些系统可能会错误地解释二进制数据中的控制字符,或者在处理二进制数据时可能会出现数据损坏。Base64编码的数据可以通过几乎所有文本处理系统而不会引起解析或格式错误。

  3. 数据完整性:使用Base64编码可以确保加密数据在存储或传输过程中的完整性,因为它将数据转换为文本格式,减少了因为环境差异导致的数据处理错误。

  4. 网络传输:在网络传输中,有些协议可能仅设计用于传输文本数据。使用Base64编码可以将二进制数据“伪装”成文本数据,从而允许这些数据通过仅支持文本数据的网络协议传输。

综上所述,使用base64.StdEncoding.EncodeToString处理AES加密后的数据是为了提高数据的可读性、兼容性和传输效率,同时保证数据的完整性。

package main

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

func main() {
 // 原始数据
 plaintext := []byte("Hello, World!")
 // 32 字节的 key (对应 AES-256)
 key := []byte("01234567890123456789012345678901")

 // 加密
 ciphertext, err := encryptCBC(key, plaintext)
 if err != nil {
  panic(err)
 }
 fmt.Printf("加密后的数据: %s\n", base64.StdEncoding.EncodeToString(ciphertext))

 // 解密
 decrypted, err := decryptCBC(key, ciphertext)
 if err != nil {
  panic(err)
 }
 fmt.Printf("解密后的数据: %s\n", decrypted)
}

func encryptCBC(key, plaintext []byte) ([]byte, error) {
 block, err := aes.NewCipher(key)
 if err != nil {
  return nil, err
 }

 // 使用 CBC 模式加密
 iv := make([]byte, aes.BlockSize)
 if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  return nil, err
 }

 // 对齐块大小
 padding := aes.BlockSize - (len(plaintext) % aes.BlockSize)
 paddedPlaintext := append(plaintext, byte(padding))
 for i := 0; i< padding-1; i++ {
  paddedPlaintext = append(paddedPlaintext, byte(0))
 }

 mode := cipher.NewCBCEncrypter(block, iv)
 ciphertext := make([]byte, len(paddedPlaintext))
 mode.CryptBlocks(ciphertext, paddedPlaintext)

 // 将 iv 附加到密文前面
 result := append(iv, ciphertext...)
 return result, nil
}

func decryptCBC(key, ciphertext []byte) ([]byte, error) {
 block, err := aes.NewCipher(key)
 if err != nil {
  return nil, err
 }

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

 // 从密文中提取 iv
 iv := ciphertext[:aes.BlockSize]
 ciphertext = ciphertext[aes.BlockSize:]

 // 使用 CBC 模式解密
 mode := cipher.NewCBCDecrypter(block, iv)
 plaintext := make([]byte, len(ciphertext))
 mode.CryptBlocks(plaintext, ciphertext)

 // 移除填充
 padding := int(plaintext[len(plaintext)-1])
 plaintext = plaintext[:len(plaintext)-padding]

 return plaintext, nil
}
;