【Go】使用Go语言实现AES CBC No Padding加密和解密


冷雨悄悄停吧

天真的心因为你

那管多风雨天仍和你一起

告诉你我其实多么的想你

其实我我真的爱着你

🎵 蒋明周《真的爱着你》


引言

高级加密标准(AES)是一种广泛使用的加密算法。它可以工作在多种模式下,最常用的一种是CBC(Cipher Block Chaining)模式。本文将介绍如何使用Go语言实现AES CBC No Padding加密和解密。

什么是AES CBC No Padding?

AES(Advanced Encryption Standard)是一种对称加密算法,意味着加密和解密使用相同的密钥。CBC(Cipher Block Chaining)是一种工作模式,它将每个明文块与前一个密文块进行异或(XOR)操作后再进行加密。No Padding表示数据块必须是加密算法所要求的固定大小,不足时不会自动填充。

准备工作

在开始编写代码之前,请确保已安装Go语言环境。可以从 Go语言官方网站 下载并安装。

代码实现

下面是完整的代码实现,包括加密和解密函数。

go 复制代码
package main

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/hex"
	"fmt"
	"log"
)

// AES加密函数
func aesEncrypt(plaintext, key, iv []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))
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext, plaintext)

	return ciphertext, nil
}

// AES解密函数
func aesDecrypt(ciphertext, key, iv []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))
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(plaintext, ciphertext)

	return plaintext, nil
}

func main() {
	key := []byte("0123456789abcdef") // 16字节的密钥
	iv := []byte("abcdef9876543210")  // 16字节的初始向量
	plaintext := []byte("Hello, AES CBC No Padding!") // 明文

	// 补充明文,使其长度为块大小的倍数
	if len(plaintext)%aes.BlockSize != 0 {
		padding := aes.BlockSize - len(plaintext)%aes.BlockSize
		plaintext = append(plaintext, bytes.Repeat([]byte{byte(padding)}, padding)...)
	}

	fmt.Printf("原始明文: %s\n", plaintext)

	// 加密
	ciphertext, err := aesEncrypt(plaintext, key, iv)
	if err != nil {
		log.Fatalf("加密失败: %v", err)
	}
	fmt.Printf("密文: %s\n", hex.EncodeToString(ciphertext))

	// 解密
	decryptedText, err := aesDecrypt(ciphertext, key, iv)
	if err != nil {
		log.Fatalf("解密失败: %v", err)
	}
	fmt.Printf("解密后的明文: %s\n", decryptedText)
}

代码说明

导入必要的包:我们使用crypto/aes和crypto/cipher包来处理AES加密和解密。

AES加密函数:

创建一个新的AES密码块。

检查明文长度是否为块大小的倍数,如果不是,则返回错误。

使用CBC加密模式进行加密。

AES解密函数:

创建一个新的AES密码块。

检查密文长度是否为块大小的倍数,如果不是,则返回错误。

使用CBC解密模式进行解密。

主函数:

定义密钥和初始向量(IV)。

补充明文,使其长度为块大小的倍数。

执行加密和解密操作,并输出结果。

运行代码

将上述代码保存为main.go,然后在终端中运行:

sh 复制代码
go run main.go

结论

本文介绍了如何使用Go语言实现AES CBC No Padding加密和解密。我们讨论了AES CBC模式的基本概念,并提供了完整的代码示例。希望这篇文章能帮助你更好地理解AES CBC加密和解密的实现。如果你有任何问题或建议,请在评论中告诉我们。

相关推荐
知无不研1 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
cfm_29142 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型
IT_陈寒3 小时前
Python的GIL让我多写了500行代码
前端·人工智能·后端
C++ 老炮儿的技术栈3 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
qq_448011163 小时前
C语言中的柔性数组
c语言·开发语言·柔性数组
小白学大数据3 小时前
长周期爬虫的数据一致性:断点续爬 + 事务回滚保障采集质量
开发语言·爬虫·测试工具
zlinear数据采集卡4 小时前
D223上位机C#开发实战:从帧解析到波形显示的完整实现
开发语言·arm开发·嵌入式硬件·fpga开发·开源·c#
Poo_Chai4 小时前
QT emit信号后完整处理流程,包括槽函数响应流程
java·开发语言·数据库
IT爱学堂4 小时前
精讲软件设计师(软考中级)一站式通关课_实战课程_慕课网
后端
瑞码空间4 小时前
Java 图形界面(GUI)完整知识点手册
java·开发语言·图形界面·swing