我正在尝试使用PyCrypto来加密/解密一些字符串,但是我在使用中文字符时遇到了麻烦。
当我尝试加密"ni-hao"(你好)时...
pemFile = open("/home/borrajax/keys/myKey.pem", "r")
encryptor = RSA.importKey(pemFile, passphrase="f00")
return encryptor.encrypt("你好", 0)[0]
。我不断收到错误:
Module Crypto.PublicKey.pubkey:64 in encrypt
>> ciphertext=self._encrypt(plaintext, K)
Module Crypto.PublicKey.RSA:92 in _encrypt
>> return (self.key._encrypt(c),)
ValueError: Plaintext too large
我尝试了很多组合,
encryptor.encrypt(u"你好"...
encryptor.encrypt(u"你好".encode("utf-8")...
没有任何运气。
我想我总是可以在编码之前尝试使用 base64,但我想将其作为"最后的资源"......我希望有一种更"优雅"的方式来做到这一点。
有没有人遇到过同样的问题?任何提示将不胜感激。提前谢谢你。
首先,您应该只加密二进制数据,而不是 Unicode 文本。这意味着str
类型(在Python 2.x中)或bytes
(在Python 3.x和最新的Python 2.x中)。必须在加密文本之前对其进行编码,并且必须在解密之后对其进行解码。
其次,您要加密的字节字符串必须小于 RSA 模数(例如,对于 RSA2048,小于 256 字节)。如果数据较长,请考虑使用中间 AES 会话密钥。
第三,如果您使用 PyCrypto 2.5,则没有充分的理由使用 RSA 密钥对象的 .encrypt/.decrypt
方法。使用 PKCS#1 方法之一更好、更安全:OAEP 或 v1.5。有了它们,明文必须更短。
我在屋岚终端的交互式解释器中使用从 Ubuntu Linux 10.04 上的 python 2.6.5 上的 pip 安装的 PyCrypto v2.5 进行了测试。
我无法重现您看到的错误,尤其是"明文太大"位。 我看到的一些错误:
encryptor.encrypt(u"你好",0)[0]
TypeError: argument 1 must be long, not unicode
似乎它不喜欢 unicode 对象 - 只想要 str。
这两种方法都适用于我的设置,并且都产生相同的输出,但是第一个解决方案更正确:
encryptor.encrypt(u"你好".encode("utf-8"), 0)[0]
encryptor.encrypt("你好", 0)[0]
您是从交互式解释器还是从文件中尝试此操作? 如果是文件,文件是否为 UTF-8 编码? 如果是控制台,它是否具有适当的 UTF-8 支持?
我检查了 PyCrypto 的相关代码,仅当纯文本(转换为 long 后)大于其中一个关键参数时才会引发此错误。假设脚本的编码设置正确,可能是因为您的 RSA 密钥无效或太短。我尝试了这个片段,它可以正常工作:
rsa = RSA.generate(1024)
print(rsa.encrypt("你好", 0))