Golang AES无填充算法实现

在Golang中实现AES无填充算法时遇到一些问题:

  1. 如何正确设置AES的加密模式为无填充?目前使用crypto/aescrypto/cipher包时,标准库默认支持PKCS#7填充,但项目需求必须禁用填充。
  2. 无填充模式下,数据长度不是块大小的整数倍会导致加密失败,有什么优雅的解决方案?是否需要手动补全数据?
  3. 使用GCM等模式时,无填充是否会影响认证标签的生成?是否有特殊注意事项?
    希望有实际代码示例说明关键步骤,谢谢!
2 回复

Golang中实现AES无填充需手动处理数据块。示例代码:

func AESEncrypt(plainText, key []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    
    // 确保数据长度为16字节倍数
    if len(plainText)%aes.BlockSize != 0 {
        return nil, errors.New("plainText length must be multiple of block size")
    }
    
    cipherText := make([]byte, len(plainText))
    for i := 0; i < len(plainText); i += aes.BlockSize {
        block.Encrypt(cipherText[i:], plainText[i:])
    }
    return cipherText, nil
}

注意:需自行确保输入数据长度符合要求,否则加密会失败。

更多关于Golang AES无填充算法实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中,AES加密默认使用PKCS#7填充。要实现无填充的AES加密,需要手动处理数据块对齐,并选择适当的加密模式(如ECB或CTR)。

以下是使用ECB模式的AES无填充实现示例:

package main

import (
	"crypto/aes"
	"fmt"
)

// ECB加密
func AESEncryptECB(plaintext, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	// 检查明文长度是否为块大小的倍数
	if len(plaintext)%aes.BlockSize != 0 {
		return nil, fmt.Errorf("plaintext is not a multiple of the block size")
	}

	ciphertext := make([]byte, len(plaintext))
	for i := 0; i < len(plaintext); i += aes.BlockSize {
		block.Encrypt(ciphertext[i:], plaintext[i:i+aes.BlockSize])
	}
	return ciphertext, nil
}

// ECB解密
func AESDecryptECB(ciphertext, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	// 检查密文长度是否为块大小的倍数
	if len(ciphertext)%aes.BlockSize != 0 {
		return nil, fmt.Errorf("ciphertext is not a multiple of the block size")
	}

	plaintext := make([]byte, len(ciphertext))
	for i := 0; i < len(ciphertext); i += aes.BlockSize {
		block.Decrypt(plaintext[i:], ciphertext[i:i+aes.BlockSize])
	}
	return plaintext, nil
}

func main() {
	key := []byte("1234567890123456") // 16字节密钥(AES-128)
	plaintext := []byte("HelloAES12345678") // 必须为16字节的倍数

	// 加密
	ciphertext, err := AESEncryptECB(plaintext, key)
	if err != nil {
		panic(err)
	}
	fmt.Printf("加密结果: %x\n", ciphertext)

	// 解密
	decrypted, err := AESDecryptECB(ciphertext, key)
	if err != nil {
		panic(err)
	}
	fmt.Printf("解密结果: %s\n", decrypted)
}

重要说明:

  1. 数据对齐:无填充要求明文/密文长度必须是16字节(AES块大小)的倍数
  2. ECB警告:ECB模式不安全,不建议用于敏感数据(相同明文块会生成相同密文块)
  3. 替代方案:推荐使用CTR模式(无需填充):
    cipher, _ := aes.NewCipher(key)
    ctr := cipher.NewCTR(stream, iv)
    ctr.XORKeyStream(ciphertext, plaintext)
    

使用时请确保:

  • 密钥长度:16字节(AES-128)、24字节(AES-192)或32字节(AES-256)
  • 数据长度符合块大小要求
  • 根据安全需求选择合适的加密模式
回到顶部