首页 > 编程语言 >Python 和 Go 实现 AES 加密算法的技术详解

Python 和 Go 实现 AES 加密算法的技术详解

时间:2024-09-12 17:23:26浏览次数:14  
标签:AES 加密 Python ciphertext time Go 加密算法

AES(Advanced Encryption Standard,高级加密标准)是一种对称密钥加密算法,广泛应用于各种安全通信场景中。AES 使用 128、192 或 256 位的密钥,能够提供不同级别的安全性。本文将详细讲解如何使用 Python 和 Go 来实现 AES 加密算法,提供代码示例并对其进行逐步解析。


1. 什么是 AES 加密算法

AES 是由美国国家标准与技术研究院(NIST)于 2001 年选定的对称密钥加密标准。其特性如下:

  • 对称性:加密和解密使用相同的密钥。
  • 分组加密:将明文数据分为若干个分组,每组 128 位(16 字节),然后逐个分组加密。
  • 安全性:AES 目前被认为是非常安全的加密算法之一,适用于大多数应用。

AES 使用三种不同的密钥长度:128 位、192 位和 256 位。加密的强度随着密钥长度的增加而提高,密钥越长,难度越大。


2. AES 加密的工作原理

AES 加密是基于分组的加密算法,通常工作在不同的模式下,包括:

  • ECB(Electronic Codebook,电子密码本)模式:每个分组独立加密。缺点是明文分组相同,加密后密文也相同,不推荐使用。
  • CBC(Cipher Block Chaining,密文分组链接)模式:每个分组的加密依赖于前一个分组的密文和初始化向量(IV),安全性更高。
  • CFB(Cipher Feedback,密文反馈)模式:类似流模式的加密方式,安全性较高。
  • GCM(Galois/Counter Mode,伽罗瓦/计数器模式):在计数器模式的基础上增加了身份验证功能,非常适合高安全性需求的场景。

AES 加密和解密的过程包括以下步骤:

  1. 生成密钥(Key)。
  2. 初始化向量(IV,适用于需要 IV 的模式,比如 CBC)。
  3. 对明文进行分组。
  4. 使用选定的模式对每个分组进行加密。
  5. 合并加密结果并输出密文。

3. 使用 Python 实现 AES 加密

Python 提供了多种加密库,其中最常用的是 pycryptodome 库,它提供了 AES 加密的全面支持。

3.1 环境配置

首先,安装 pycryptodome 库:

pip install pycryptodome

3.2 Python 示例代码

我们将使用 CBC 模式来实现 AES 加密,示例如下:

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes

# 生成密钥和初始化向量
key = get_random_bytes(16)  # 16 字节的密钥(128 位)
iv = get_random_bytes(16)   # 16 字节的 IV

# 加密函数
def aes_encrypt(plaintext):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_text = pad(plaintext.encode('utf-8'), AES.block_size)
    ciphertext = cipher.encrypt(padded_text)
    return ciphertext

# 解密函数
def aes_decrypt(ciphertext):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_plaintext = cipher.decrypt(ciphertext)
    plaintext = unpad(padded_plaintext, AES.block_size)
    return plaintext.decode('utf-8')

# 示例使用
plaintext = "Hello, AES in Python!"
ciphertext = aes_encrypt(plaintext)
print(f"密文: {ciphertext}")

# 解密
decrypted_text = aes_decrypt(ciphertext)
print(f"解密后的明文: {decrypted_text}")

3.3 代码详解

  1. 生成密钥和 IVget_random_bytes(16) 用于生成 16 字节(128 位)的随机密钥和初始化向量(IV)。CBC 模式要求 IV 必须与密钥的长度相同。
  2. 加密过程
  • 使用 AES.new() 初始化 AES 加密对象,指定模式为 AES.MODE_CBC 并传入密钥和 IV。
  • 使用 pad() 方法对明文进行填充,使其长度为 AES 的分组大小的倍数(16 字节)。
  • 使用 encrypt() 方法对填充后的明文进行加密。
  1. 解密过程
  • 使用与加密时相同的密钥和 IV 初始化 AES 解密对象。
  • 使用 decrypt() 方法对密文进行解密,得到填充后的明文。
  • 使用 unpad() 方法去除填充,恢复原始明文。

4. 使用 Go 实现 AES 加密

Go 语言中使用 crypto/aescrypto/cipher 包可以轻松实现 AES 加密。

4.1 环境配置

Go 标准库已经包含了 AES 加密所需的包,无需额外安装。

4.2 Go 示例代码

下面是使用 Go 实现 AES-CBC 模式的代码:

package main

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

// 生成 32 字节的密钥(256 位 AES)
func generateKey() []byte {
	key := sha256.Sum256([]byte("mysecretpassword"))
	return key[:]
}

// AES 加密函数
func aesEncrypt(plaintext string, key []byte) (string, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
	iv := ciphertext[:aes.BlockSize]

	// 生成随机 IV
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return "", err
	}

	stream := cipher.NewCBCEncrypter(block, iv)
	stream.CryptBlocks(ciphertext[aes.BlockSize:], []byte(plaintext))

	return hex.EncodeToString(ciphertext), nil
}

// AES 解密函数
func aesDecrypt(cipherHex string, key []byte) (string, error) {
	ciphertext, _ := hex.DecodeString(cipherHex)
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	stream := cipher.NewCBCDecrypter(block, iv)
	stream.CryptBlocks(ciphertext, ciphertext)

	return string(ciphertext), nil
}

func main() {
	plaintext := "Hello, AES in Go!"

	// 生成密钥
	key := generateKey()

	// 加密
	ciphertext, err := aesEncrypt(plaintext, key)
	if err != nil {
		fmt.Println("加密错误:", err)
		return
	}
	fmt.Println("加密后的密文:", ciphertext)

	// 解密
	decryptedText, err := aesDecrypt(ciphertext, key)
	if err != nil {
		fmt.Println("解密错误:", err)
		return
	}
	fmt.Println("解密后的明文:", decryptedText)
}

4.3 代码详解

  1. 生成密钥:使用 sha256.Sum256() 方法生成 256 位的密钥。
  2. 加密过程
  • 使用 aes.NewCipher() 方法创建 AES 加密块,要求密钥长度为 16、24 或 32 字节。
  • 生成随机 IV,并创建 CBC 加密器 cipher.NewCBCEncrypter()
  • 使用 CryptBlocks() 方法对明文进行加密,并将结果编码为十六进制字符串输出。
  1. 解密过程
  • 读取 IV 并使用与加密相同的密钥创建解密器 cipher.NewCBCDecrypter()
  • 使用 CryptBlocks() 解密密文,返回解密后的明文。

5. Python 与 Go 实现的性能比较

5.1 性能测试

我们可以通过对 Python 和 Go 的 AES 实现进行相同条件下的性能测试来评估它们的执行效率。

  • 加密时间:Go 通常比 Python 更快,主要得益于其编译型语言的特性和更好的内存管理。
  • 易用性:Python 的库提供了更高层次的抽象,代码简洁,而 Go 需要更多的手动管理操作。

5.2 结果对比

为了对比 Python 和 Go 在 AES 加密上的性能,我们可以对相同大小的数据进行加密和解密操作,并测量它们的耗时。

假设我们使用相同的硬件环境进行实验,处理 1 MB 的数据,并分别记录 Python 和 Go 的执行时间。

# Python AES 性能测试
import time

# 加密性能测试
start_time = time.time()
for _ in range(100):
    aes_encrypt("A" * 1024 * 1024)
end_time = time.time()
print(f"Python 加密 100 次的总时间: {end_time - start_time} 秒")

# 解密性能测试
start_time = time.time()
for _ in range(100):
    aes_decrypt(ciphertext)
end_time = time.time()
print(f"Python 解密 100 次的总时间: {end_time - start_time} 秒")

在 Go 中,我们可以使用类似的方式进行性能测试:

package main

import (
	"fmt"
	"time"
)

func performanceTest() {
	plaintext := "A" * 1024 * 1024  // 1 MB 数据
	key := generateKey()

	// 加密性能测试
	start := time.Now()
	for i := 0; i < 100; i++ {
		_, err := aesEncrypt(plaintext, key)
		if err != nil {
			fmt.Println("加密错误:", err)
			return
		}
	}
	fmt.Printf("Go 加密 100 次的总时间: %v\n", time.Since(start))

	// 解密性能测试
	ciphertext, _ := aesEncrypt(plaintext, key)
	start = time.Now()
	for i := 0; i < 100; i++ {
		_, err := aesDecrypt(ciphertext, key)
		if err != nil {
			fmt.Println("解密错误:", err)
			return
		}
	}
	fmt.Printf("Go 解密 100 次的总时间: %v\n", time.Since(start))
}
性能分析
  1. 执行速度:通常,Go 的 AES 加密执行时间会比 Python 更快,因为 Go 是编译型语言,直接生成机器代码,执行效率更高。而 Python 是解释型语言,运行时的动态解析会消耗额外的时间。
  2. 内存管理:Python 的内存管理相对更自动化,开发者可以专注于应用逻辑,而不需要过多考虑内存泄露等问题。然而,这种自动化也会带来额外的开销。相比之下,Go 的内存管理机制更为直接和轻量,因此在处理大数据加密时,其性能表现更加出色。
  3. 代码复杂度:从代码编写的角度来看,Python 的加密库提供了更多高级封装,使得代码更加简洁和易于理解。Go 由于其系统级语言的特性,代码通常需要更详细的管理步骤,比如 IV 的生成和加密块的显式管理。

6. 总结

在这篇文章中,我们通过实例演示了如何使用 Python 和 Go 来实现 AES 加密算法,并对它们的性能进行了比较。我们得出以下结论:

  • Python 实现:使用 pycryptodome 库实现 AES 加密相对简单,代码易于阅读和编写,非常适合需要快速实现安全加密的场景。然而,Python 的执行速度相对较慢,不适合需要高性能的场合。
  • Go 实现:Go 的标准库中提供了 AES 加密功能,虽然实现上需要更多的代码和手动管理,但其执行效率高,适合处理需要高性能的加密任务。

选择建议

  • 对于开发速度要求较高的项目,建议使用 Python 实现 AES 加密,特别是在安全需求较高但性能需求不太关键的情况下,Python 提供了非常方便的库和简单的代码。
  • 对于需要处理大量加密数据、要求高性能的场景,Go 的 AES 实现更加适合,因为 Go 语言能更好地利用系统资源,并且其编译特性使得执行效率更高。

AES 加密作为对称加密的核心算法之一,在 Python 和 Go 中都有出色的支持。根据项目的具体需求,可以灵活选择合适的语言和实现方式。

标签:AES,加密,Python,ciphertext,time,Go,加密算法
From: https://blog.51cto.com/u_16170163/11992274

相关文章

  • Python文件操作:文件的读取和写入(文本文件、二进制文件)①
    文章目录1.文件操作基础1.1打开文件1.2关闭文件2.文本文件操作2.1读取文本文件2.1.1逐行读取2.1.2读取所有内容2.1.3读取所有行2.2写入文本文件2.2.1写入内容2.2.2追加内容3.二进制文件操作3.1读取二进制文件3.2写入二进制文件4.综合示例4.1示例描......
  • 基于MicroPython的ESP8266控制RGB颜色传感器识别颜色的设计方案
        以下是一个基于MicroPython的ESP8266控制RGB颜色传感器进行颜色识别的设计方案:一、硬件准备1. ESP8266开发板(如NodeMCU)。2. RGB颜色传感器(例如TCS3200传感器)。3. 面包板。4. 杜邦线若干。5.3.3V直流电源二、硬件连接1. 将ESP8266的3.3V引脚、GND......
  • 基于MicroPython的ESP8266控制舵机的设计方案
        以下是一个基于MicroPython的ESP8266控制舵机的设计方案: 一、硬件准备1. ESP8266开发板(如NodeMCU)。2. 舵机(如SG90)。3. 杜邦线若干。 二、硬件连接1.将5V直流电源连接到舵机的电源引脚(通常为红色线)。2.将3.3V直流电源连接到ESP8266的3.3V管脚。3......
  • python利用matplot绘制横向条形图,并调整每个条形的位置
    通过color_x和t_x控制每个条形的颜色和文本,draw_mybar里的y和left可以控制条形显示的位置。importmatplotlib.pyplotaspltimportnumpyasnp#数据设置categories=["A","B","C","D"]color_1="#9dc3e4"color_2="#f8cbbd"color_3=......
  • python基于django框架医院管理系统设计与实现mysql数据库
    随着信息技术的快速发展和医疗卫生事业的不断进步,医院信息化管理已成为提高医疗服务质量和效率的重要手段。本文设计并实现了一个基于PythonDjango框架的医院管理系统,旨在为医院提供一个全面、高效、易用的信息化管理平台。本系统采用Django框架作为后端开发框架,利用其强大......
  • ubuntu22.04安装python2+python命令软链接修改
      ubuntu22.04安装python2+python命令软链接修改问题由来:新版本的ubuntu默认安装python3,且可能默认的运行命令为python3,而非python。除此之外,一些古早的代码底层可能用的python2。因此,本文简单讲述如何在高版本系统中安装python2,并添加python命令(软链接)1python2安装(1)apt-ge......
  • 揭秘Python:对象类型打印
    一、Python数据类型简介在Python的世界中,了解你正在处理的数据类型是至关重要的。Python提供了多种内置数据类型,包括数字(整数和浮点数)、字符串、列表、元组、字典等。这些数据类型决定了你可以对数据执行哪些操作,以及如何高效地存储和处理数据。1.数字类型数字类型是最基本的数据......
  • Java开发者无痛丝滑入门Python
    哈喽各位道友,经过两周的更新,凡人编程传的第一个“系列”学习笔记《Python基础》已经全部上线啦,现在免费分享给大家,学习路线在下面,点击链接即可跳转对应笔记。这套笔记有什么不一样的地方呢?这套笔记适合有一定Java编程基础的道友,因为笔记语言比较简练,大多只讲重点,避免了啰嗦......
  • python+opencv图片文字旋转矫正
    最近在使用实在RPA做机器人自动化,功能是受理单核对,即对核对业务受理人是否上传受理单承诺书方法很简单,由于系统中图片位置不固定,所以需要将所有附件进行下载,并进行图像文字识别,但是实在RPA中的OCR识别无法识别颠倒倾斜的图片,所以有两种方法,一种是使用其他OCR模型,一种是将图片旋转......
  • python定时任务解决方案
    在Python中,有多种方式可以实现定时任务。以下是一些常见的解决方案:1.Celery概述:Celery是一个强大的异步任务队列,支持延迟执行和定时任务。特点:支持多种消息代理,如RabbitMQ和Redis。可以使用celerybeat来调度定时任务。支持任务重试、结果存储等功能。适用......