Python pycryptodome类库使用学习总结

news/2024/9/20 0:16:26

AES数据加解密

以下代码生成一个新的AES-128密钥,并将一段数据加密到一个文件中。我们使用 CTR 模式(这是一种 经典操作模式, 简单但不再推荐)。
仅使用CTR,接收者无法检测到密文(即加密数据)在传输过程中是否被修改。为了应对这种风险,例中还附加了一个MAC身份验证标签(采用SHA256模式的HMAC),该标签由第二个密钥制成。

# -*- coding:utf-8 -*-from Crypto.Cipher import AES
from Crypto.Hash import HMAC, SHA256
from Crypto.Random import get_random_bytesdata = 'secret data to transmit'.encode()aes_key = get_random_bytes(16) # 返回一个包含适合加密使用的随机字节的字节对象
print('aes_key: ', aes_key) # aes_key:  b'\xf6Ke|/M\x93tv\n\xec\x1ej\xb4k\xab'cipher = AES.new(aes_key, AES.MODE_CTR) # 创建一个 AES cipher
ciphertext = cipher.encrypt(data) # 加密数据,返回字节对象hmac_key = get_random_bytes(16)
print('hmac_key: ', hmac_key) # hmac_key:  b'hU\xe6O\x8a\xc5\xa4g\xf3"\xc1K,f\x96\xdb'hmac = HMAC.new(hmac_key, digestmod=SHA256)
tag = hmac.update(cipher.nonce + ciphertext).digest()with open("encrypted.bin", "wb") as f:f.write(tag)f.write(cipher.nonce)f.write(ciphertext)# 与接收者安全共享 aes_key和hmc_key
# encrypted.bin 可通过非安全信道传输

最后,接收者可以安全地加载回数据(如果他们知道这两个密钥(aes_keyhmc_key的话))。请注意,当检测到篡改时,代码会抛出ValueError异常。

import sys
from Crypto.Cipher import AES
from Crypto.Hash import HMAC, SHA256aes_key = b'\xf6Ke|/M\x93tv\n\xec\x1ej\xb4k\xab'
hmac_key = b'hU\xe6O\x8a\xc5\xa4g\xf3"\xc1K,f\x96\xdb'with open("encrypted.bin", "rb") as f:tag = f.read(32)nonce = f.read(8)ciphertext = f.read()try:hmac = HMAC.new(hmac_key, digestmod=SHA256)tag = hmac.update(nonce + ciphertext).verify(tag)
except ValueError:print("The message was modified!")sys.exit(1)cipher = AES.new(aes_key, AES.MODE_CTR, nonce=nonce)
message = cipher.decrypt(ciphertext) # 解密数据,返回字节对象
print("Message:", message.decode())  # 输出:Message: secret data to transmit

一步完成数据加密和验证

上一节中的代码包含三个微妙但重要的设计决策:ciphernonce经过验证,验证在加密后执行,且加密和验证使用两个不相关的密钥。安全地组合加密原语并不容易,因此已经创建了更现代的加密cipher模式,OCB mode (查阅其它 经过身份验证的加密模式 如 EAX, GCM, CCM, SIV)。

# -*- coding:utf-8 -*-from Crypto.Cipher import AES
from Crypto.Random import get_random_bytesdata = 'secret data to transmit'.encode()aes_key = get_random_bytes(16)
print('aes_key: ', aes_key) # aes_key:  b'p.\xb7iD\x8a\xb6\xdc\x1e\x80E\xf4k:\xb4q'cipher = AES.new(aes_key, AES.MODE_OCB)
ciphertext, tag = cipher.encrypt_and_digest(data)
assert len(cipher.nonce) == 15with open("encrypted.bin", "wb") as f:f.write(tag)f.write(cipher.nonce)f.write(ciphertext)# 与接收者安全共享 aes_key
# encrypted.bin 可通过非安全信道传输

数据解密

# -*- coding:utf-8 -*-from Crypto.Cipher import AESaes_key = b'p.\xb7iD\x8a\xb6\xdc\x1e\x80E\xf4k:\xb4q'with open("encrypted.bin", "rb") as f:tag = f.read(16)nonce = f.read(15)ciphertext = f.read()cipher = AES.new(aes_key, AES.MODE_OCB, nonce=nonce)
try:message = cipher.decrypt_and_verify(ciphertext, tag)
except ValueError:print("The message was modified!")exit(1)print("Message:", message.decode())

RSA数据加解密

生成RSA秘钥

以下代码生成一个新的RSA密钥对(secret),并将其保存到一个受密码保护的文件中。使用 脚本 密钥推导函数,以阻止字典攻击。最后,代码以ASCII/PEM格式打印RSA公钥:

from Crypto.PublicKey import RSAsecret_code = "Unguessable"
key = RSA.generate(2048)
encrypted_key = key.export_key(passphrase=secret_code, pkcs=8,protection="scryptAndAES128-CBC",prot_params={'iteration_count':131072})with open("rsa_key.bin", "wb") as f:f.write(encrypted_key)print(key.publickey().export_key())

以下代码读取私钥RSA,然后再次打印公钥

from Crypto.PublicKey import RSAsecret_code = "Unguessable"
encoded_key = open("rsa_key.bin", "rb").read()
key = RSA.import_key(encoded_key, passphrase=secret_code)print(key.publickey().export_key())

生成公钥和私钥

以下代码生成存储在receiver.pem中的公钥和存储在private.pem中的私钥。这些文件将在下面的示例中使用。每次生成不同的公钥和私钥对。

from Crypto.PublicKey import RSAkey = RSA.generate(2048)
private_key = key.export_key()
with open("private.pem", "wb") as f:f.write(private_key)public_key = key.publickey().export_key()
with open("receiver.pem", "wb") as f:f.write(public_key)

使用RSA加解密数据

以下代码为我们拥有RSA公钥的接收者加密了一段数据。RSA公钥存储在一个名为receiver.pem的文件中。

为了能够加密任意数量的数据,使用混合加密方案。为AES会话密钥的非对称加密,使用RSA及PKCS1OAEP 。然后,会话密钥可用于加密所有实际数据。

与第一个示例一样,使用EAX模式来检测未经授权的修改

from Crypto.PublicKey import RSA
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES, PKCS1_OAEPdata = "I met aliens in UFO. Here is the map.".encode("utf-8")recipient_key = RSA.import_key(open("receiver.pem").read())
session_key = get_random_bytes(16)# 使用公钥加密会话key
cipher_rsa = PKCS1_OAEP.new(recipient_key)
enc_session_key = cipher_rsa.encrypt(session_key)# 使用AES会话key加密数据
cipher_aes = AES.new(session_key, AES.MODE_EAX)
ciphertext, tag = cipher_aes.encrypt_and_digest(data)with open("encrypted_data.bin", "wb") as f:f.write(enc_session_key)f.write(cipher_aes.nonce)f.write(tag)f.write(ciphertext)

接收方拥有RSA私钥。将首先使用它解密会话密钥,然后解密文件的其余部分::

from Crypto.PublicKey import RSA
from Crypto.Cipher import AES, PKCS1_OAEPprivate_key = RSA.import_key(open("private.pem").read())with open("encrypted_data.bin", "rb") as f:enc_session_key = f.read(private_key.size_in_bytes())nonce = f.read(16)tag = f.read(16)ciphertext = f.read()# 使用私钥解密会话key
cipher_rsa = PKCS1_OAEP.new(private_key)
session_key = cipher_rsa.decrypt(enc_session_key)# 使用AES会话key解密数据
cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
data = cipher_aes.decrypt_and_verify(ciphertext, tag)
print(data.decode("utf-8"))

参考连接

https://www.pycryptodome.org/src/examples

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/62342.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

电脑设置系统不自动更新

1、win + R 2、计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\StateVariables 3、右边空白处右击 -> 新建 -> DWORD值,命名为FlightSettingsMaxPauseDays,点击基数选择十进制,数值设置为9999(表示不更新的天数)

同花顺--涨停板改变颜色

复制以下代码 IF(C>=REF(C,1)*1.095 AND C=H) RETURN "涨停"; 然后进行操作: 1、打开同花顺软件,右击K线,单击修改K线2、光标挪到代码首行行首,回车换行3、粘贴一下4、点击设置标志5、命名为涨停,选颜色,填充打勾6、点击确定

关于零值和nil

1. 零值 零值是指当你声明变量(分配内存)并未显式初始化时,始终为你的变量自动设置一个默认初始值的策略。 对于值类型:布尔类型为 false, 数值类型为 0,字符串为 "",数组和结构会递归初始化其元素或字段,即其初始值取决于元素或字段。 对于引用类型: 均为 n…

利用AutoGpt将任何模型支持o1模型的推理实现

利用AutoGpt将任何模型支持o1模型的推理实现 相信大家都对于OpenAI最新出的o1模型都非常关注,它已经能通过推理让回复的效果更加理想, 但是目前o1的限制太大,而且使用o1至少也是需要购买OpenAI官方的会员价格也在20美刀(好贵!!),于是乎社区出现非常多相似的实现,通过更…

C语言类型与强制类型转换

目录类型关键字sizeof如何理解强制类型转化不同类型的0null字符设备(补充) char有有符号和无符号两种类型,字符是无符号类型.(补充) getchar的返回值为什么是int键盘输入的内容,以及往显示器中打印的内容,都是字符 --> 键盘/显示器称为字符设备 类型C语言为何有类型? 让我们…

访问Github卡顿甚至进不去的解决办法(适用于Windows)

本文使用Watt Tookit(原Steam++)解决了Github在国内访问速度卡顿甚至无反应的问题,通过NDM和镜像网站实现Github大文件高速下载。本文首发自个人博客:点我查看 一、前言 Github 是全球知名的开源宝库,但是对国内用户并不友好。当我们在浏览器中输入www.github.com时,如果…

如何在 ASP.NET Core Web API 方法执行前后 “偷偷“ 作一些 “坏“ 事?初识 ActionFilterAttribute

ActionFilterAttribute 是一种作用于控制器 Action 方法的特性(Attribute),通过它,你可以在操作执行前后、异常处理时等不同的阶段插入自定义逻辑。 比如在执行操作方法之前修改请求参数、记录日志、进行权限验证等操作,在执行操作方法之后发送邮件、同步数据等等。 本文主…

看看mysql干的恶心事

MySQL是一个关系型数据库管理系统,最初由瑞典的MySQL AB公司开发。该公司后来被Sun公司收购,而Sun公司随后又被Oracle公司收购。因此,目前MySQL属于Oracle旗下的产品。MySQL以其体积小、速度快、总体拥有成本低的特点,成为了最流行的关系型数据库管理系统之一,特别是在WEB…