2

我正在尝试使用 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,但我想把它作为“最后的资源”......我希望有一种更“优雅”的方式来做到这一点。

有没有人遇到过同样的问题?任何提示将不胜感激。先感谢您。

4

3 回答 3

2

首先,您应该只加密二进制数据,而不是 Unicode 文本。这意味着str类型(在 Python 2.x 中)或bytes(在 Python 3.x 和最新的 Python 2.x 中)。您必须在加密之前对文本进行编码,并且在解密之后必须对其进行解码。

其次,您要加密的字节串必须小于 RSA 模数(例如,对于 RSA2048,小于 256 个字节)。如果您的数据较长,请考虑使用中间 AES 会话密钥。

第三,如果您使用 PyCrypto 2.5,则没有充分的理由使用.encrypt/.decryptRSA 密钥对象的方法。使用 PKCS#1 方法之一会更好、更安全:OAEPv1.5。有了它们,明文必须更短。

于 2012-04-11T06:27:40.513 回答
1

我在 yakuake 终端的交互式解释器中使用从 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 支持?

于 2012-04-11T00:40:52.550 回答
1

我检查了 PyCrypto 的相关代码,仅当纯文本(转换为长文本后)大于关键参数之一时才会引发此错误。假设脚本的编码设置正确,可能是因为您的 RSA 密钥无效或太短。我试过这个片段,它没有问题:

rsa = RSA.generate(1024)

print(rsa.encrypt("你好", 0))
于 2012-04-11T00:52:36.087 回答