我正在尝试使用RSA对整数进行加密。
我观察到我可以加密一个字符串,但不能加密一个整数。
下面是相关的代码片段:
无法加密整数,4:
crypto:~$ python
Python 2.7.3 (default, Aug 1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from Crypto.PublicKey import RSA
>>> input=4
>>> rsa=RSA.generate(1024)
>>> print rsa.encrypt(input,"")[0].encode('hex')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/Crypto/PublicKey/pubkey.py", line 64, in encrypt
ciphertext=self._encrypt(plaintext, K)
File "/usr/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 71, in _encrypt
return (self.key._encrypt(c),)
TypeError: must be long, not int
>>> 现在,我将这个数字表示为十六进制字符串,它是有效的:
crypto:~$ python
Python 2.7.3 (default, Aug 1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from Crypto.PublicKey import RSA
>>> input='\x04'
>>> rsa=RSA.generate(1024)
>>> print rsa.encrypt(input,"")[0].encode('hex')
09f7d33972b0b6b72136f8aef0c8ba4446afad0dcf65337cd8b6c48c3758f5455e19e9c1ecbd058d7f83bcaa1f860b1ea0197d83f91fa958e6c9a2664a7ebee77c41fbfc4d3960e98afc0d94d1af8a230c4d86fce53f4c7ac72ae40a8acb101b40de6d46fe8e3cb7265f253b410a95a255e5fad0d0438d1fc62ad1feb96d331f使用inspect模块,我检查了RSA对象的encrypt函数的源代码,发现它既可以加密字符串,也可以加密整数明文:
crypto:~$ python
Python 2.7.3 (default, Aug 1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import inspect
>>> from Crypto.PublicKey import RSA
>>> rsa=RSA.generate(1024)
>>> rsa
<_RSAobj @0x29c1368 n(1024),e,d,p,q,u,private>
>>> print inspect.getsource(rsa.encrypt)
def encrypt(self, plaintext, K):
"""encrypt(plaintext:string|long, K:string|long) : tuple
Encrypt the string or integer plaintext. K is a random
parameter required by some algorithms.
"""
wasString=0
if isinstance(plaintext, types.StringType):
plaintext=bytes_to_long(plaintext) ; wasString=1
if isinstance(K, types.StringType):
K=bytes_to_long(K)
ciphertext=self._encrypt(plaintext, K)
if wasString: return tuple(map(long_to_bytes, ciphertext))
else: return ciphertext那么,为什么当我尝试使用RSA对象加密一个数字时,它会给出一个错误?
为什么它期望输入是长格式而不是整型?
发布于 2013-07-15 01:49:56
回溯清楚地表明rsa.encrypt需要一个long类型的参数。如果它是一个字符串,它会将其转换为long类型。
rsa.encrypt(4L,"")这将会起作用,4L仍然是一个数字,但它的类型是long。
我认为询问long的原因是,要执行加密,您必须进行一些填充,然后在填充的数字上执行。这个数字非常长,对于sha1来说,它是512的倍数。因此对于一个至少512的数字,int不能满足需要。那么久是问了。从inspect的结果可以看出,它只将类型转换为string,没有int。所以如果你传递一个int,它就是错误的。除了破解模块的源代码之外,你别无选择。
在很长一段时间内,它返回一个long。也许你可以使用下面的代码来进行编码:
hex(rsa.encrypt(4L, '')[0]).rstrip('L').lstrip(0x)
'31bf11047cbe9115541e29acb5046d98f2a9bdc44d4768668e9119f8eca24bf24dfc4ac070950734e819675f93e1809859b750df63e8bc71afc7c83edfc6d2f59f495c8e378e0633f07e21672a7e862cfa77a6aede48075dec0cd2b1d8c016dade779f1ea8bd9ffa8ef314c4e391b0f5860cf06cb0f991d2875c49722e98b94f'此外,您还可以将整数更改为bytes:rsa.encrypt(input, '')[0].encode('hex')。输入是struct.pack('b', 4)。
发布于 2013-07-15 02:23:42
Python 2.x有两种类型的整数:
int类型,匹配本地平台上的C类型long。精度是有限的,但至少是32位。long类型,它具有无限精度。PyCrypto中的RSA对象的encrypt和decrypt方法仅适用于long或二进制字符串,不适用于int。PyCrypto's API中记录了这一点。
从理论上讲,您可以通过使用函数long()将整数强制为所需的类型来修复代码,但值得指出的是,您的代码将不安全。
RSA加密应该使用OAEP padding和字节字符串作为输入/输出。
发布于 2019-05-07 15:59:27
然而,不幸的是,在Python3中,似乎不能再使用l、L或The input variable should be (byte string or long) ()来定义长变量。
https://stackoverflow.com/questions/17641868
复制相似问题