Python AES加密无需额外模块

23

是否可以在不安装额外模块的情况下使用AES加密/解密数据?我需要发送/接收使用 System.Security.Cryptography 引用进行加密的数据到 C#

更新 我尝试使用了PyAES,但它太旧了。我更新了一些东西使其工作,但没有成功。 我也不能安装,因为它的最新版本是3.3,而我的版本是3.4


1
当然,如果您不介意速度慢的话,手动进行AES加密并不难。或者,您可以通过ctypes访问Windows加密API,或者使用openssl。但使用一个易于操作的模块会更好。您不想使用这样的模块有原因吗?(请注意,官方文档明确指出pycrypto可用于此类操作。) - abarnert
C# 部分已经可以工作,问题出在 Python 上。我总是在安装 Python 模块时遇到麻烦,所以如果有可能不使用额外的模块来使用 AES 就最好了。加密/解密的速度最多可以达到 200ms,这是为了聊天而设计的。 - Anton
7
如果你在安装Python模块时遇到问题,那么你应该解决这个问题而不是忽略它。如果你的Python安装损坏了,修复它或重新安装。如果你不知道pipChristoph Gohlke 的Windows二进制包仓库,那就了解一下它们。 - abarnert
另一种可能性是:您可以使用IronPython而不是CPython吗?然后,您可以像从C#一样轻松地从Python访问System.Security.Cryptography - abarnert
1
截至2015/12/18,pyaes似乎在Python 3.4上运行良好,至少对于简单的用例(CTR加密/解密)是如此。 - Giacomo Lacava
6个回答

16

我正在使用 加密 库。

加密是一个活跃开发的库,提供了密码学配方和基元。它支持 Python 2.6-2.7、Python 3.3+ 和 PyPy。

{{link2:请参阅此文档} }以获取如何使用该库的示例:

import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

# Pseudo-random key and initialisation vector
key = os.urandom(32)           # (32*8=256-bit. AES also accepts 128/192-bit)
init_vector = os.urandom(16)   # (16*8=128-bit. AES only accepts this size)

# Setup module-specific classes
cipher = Cipher(algorithms.AES(key), modes.CBC(init_vector))
encryptor = cipher.encryptor()
decryptor = cipher.decryptor()

# Encrypt and decrypt data
cyphertext = encryptor.update(b"a secret message") + encryptor.finalize()
plaintext = decryptor.update(cyphertext) + decryptor.finalize()
print(plaintext) # 'a secret message'

一些解释示例代码的注释:

  • 使用os.urandom来进行安全操作,而不是Python的random模块。更多详情请参见此答案
  • 这篇文章详细介绍了为什么要使用初始化向量以及AES加密中的CBC(密码块链接)模式。
  • 相关文档详细说明了与cryptography模块相关的类,例如algorithmsmodes:“Cipher对象将AES等算法与CBC或CTR等模式结合起来。”
  • 旧版本库(<3.1)需要backend对象。自36.0版本以来,该对象已弃用。

我完全支持这个答案。Cryptography库正在积极维护;其他答案中提到的库(PyCrypto、PyAES)已经不再维护。 - Daira Hopwood
这个实现在我的电脑上似乎比Crypto.Cipher AES慢(速度的2/3)。 - k3it
请注意,使用Hazmat时要小心处理龙和地雷,除非您确实知道自己在做什么。 :) - Brōtsyorfuzthrāx
那么,您如何使其加密任意长度的消息,并使用任意长度的密钥? - Brōtsyorfuzthrāx
我的意思是,你知道使用GNU Privacy Guard时,在指定AES对称加密时可以这样做吗?他们实际上是如何做到的? - Brōtsyorfuzthrāx

15

PYAES可以与任何版本的Python3.x一起使用,不需要修改库。

以下是pyaes CTR模式的Python3.x完整工作示例 (https://github.com/ricmoo/pyaes)

import pyaes

# A 256 bit (32 byte) key
key = "This_key_for_demo_purposes_only!"
plaintext = "Text may be any length you wish, no padding is required"

# key must be bytes, so we convert it
key = key.encode('utf-8')

aes = pyaes.AESModeOfOperationCTR(key)    
ciphertext = aes.encrypt(plaintext)

# show the encrypted data
print (ciphertext)

# DECRYPTION
# CRT mode decryption requires a new instance be created
aes = pyaes.AESModeOfOperationCTR(key)

# decrypted data is always binary, need to decode to plaintext
decrypted = aes.decrypt(ciphertext).decode('utf-8')

# True
print (decrypted == plaintext)

如果您遇到任何错误,请告诉我。


1
这是我最喜欢的答案。 pyaes是一个库,您可以直接将其放入代码中而无需安装。无需安装任何东西 - 只需下载并放置在您的项目中即可。 - Gil Allen
FYI:PYAES 采用 MIT 许可证(对于那些不想要点击链接查看的人)。 - Brōtsyorfuzthrāx

9
标准库中提供的加密服务是这些。可以看到,AES没有列出,但建议使用pycrypto,这是一个额外的模块。
只需使用pipeasy_install安装它,然后按照pycrypto页面上的说明操作即可。
from Crypto.Cipher import AES
obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
message = "The answer is no"
print obj.encrypt(message)

如果不使用额外的模块,唯一的另一种方法就是自己编写这个函数,但下载一个额外的模块并使用它有什么区别呢?

如果您想要一个纯Python实现的AES,可以下载和导入pyaes,请查看pyaes


我的回答是,如果你不想(或不能)安装模块,你也可以下载完整的pycrypto源代码并将其放置在你的代码旁边。 - enrico.bacis
1
这仅适用于纯Python包;PyCrypto主要是C扩展,您需要构建它们。 - abarnert
那也不起作用,版本太旧了。你认为如果我修复print()函数,它会起作用吗? - Anton
我更新了一些代码,但这是用于加密文件而不仅仅是文本。我认为我可以通过一些编辑使其工作。 - Anton
这种方式不起作用,我因错误过多而超载(我猜是因为版本错误)。 - Anton
显示剩余2条评论

4

这里是一个适用于Python 3的自包含的AES实现

使用示例:

aesmodal = AESModeOfOperation() 
key = [143,194,34,208,145,203,230,143,177,246,97,206,145,92,255,84]
iv = [103,35,148,239,76,213,47,118,255,222,123,176,106,134,98,92]

size = aesmodal.aes.keySize["SIZE_128"]

mode,orig_len,ciphertext = aesmodal.encrypt("Hello, world!", aesmodal.modeOfOperation["OFB"], key, size, iv)
print(ciphertext)
plaintext = aesmodal.decrypt(ciphertext, orig_len, mode, key, size, iv)
print(plaintext)

2
为什么这个名字这么奇怪? :0 - BartoszKP
1
因为你的最后一行是 print plaintext,所以在 Python 3 中会出现问题。我认为你需要将其作为一个函数调用。 - Electron
4
链接失效。 - zaph

3
要补充 @enrico.bacis 的回答:AES 没有在标准库中实现。它在 PyCrypto 库中实现,该库稳定并经过充分测试。如果需要使用 AES,请将 PyCrypto 添加为代码的依赖项。
尽管理论上可以很简单地在纯 Python 中编写 AES 原语的实现,但强烈建议不要这样做。这是密码学的第一条规则:不要自己实现。特别是如果你只是在编写自己的加密库,几乎肯定会让自己暴露于某种侧信道攻击的风险中。

1
我无法使用PyCrypto,因为它不支持Python 3.4。 - Anton

2

Python 3.6与密码学模块

from cryptography.fernet import Fernet
key = Fernet.generate_key()
f = Fernet(key)
token = f.encrypt(b"my deep dark secret")
print(token)


f.decrypt(token)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接