在python Crypto包中似乎存在RSA加密/解密问题:
from Crypto.PublicKey import RSA
from os import urandom
def test(keylen, datalen, rand_len):
k = RSA.generate(keylen)
ok, fail = (0,0)
for i in range(1000):
a = urandom(datalen)
if a == k.decrypt(k.encrypt(a, urandom(rand_len))):
ok += 1
else:
fail += 1
return ok, fail
无论我的keylen / datalen / rand_len是什么组合,我都无法让它在100%的时间内解密。它只是我安装的Crypto吗?
>>> test(1024,128,0)
(853, 147)
>>> test(1024,127,0)
(996, 4)
>>> test(2048,127,0)
(994, 6)
答案 0 :(得分:3)
试试这个:
from Crypto.PublicKey import RSA
from os import urandom
def test(keylen, datalen, rand_len):
k = RSA.generate(keylen)
ok, fail = (0,0)
for i in range(1000):
a = urandom(datalen).lstrip(b'\x00')
if a == k.decrypt(k.encrypt(a, urandom(rand_len))):
ok += 1
else:
fail += 1
return ok, fail
说明:
pycrypto对数字进行操作,而不是对内部字节进行操作,这意味着不会考虑前导零。 encrypt
和decrypt
非常低级。
用于签名你应该使用Signature
包(pycrypto2.5 +),它负责正确填充你的消息。否则你必须自己填写你的信息。
答案 1 :(得分:1)
对于以NUL(\x00'
)开头的输入字符串,每个解密失败都会发生。如果您将原始字符串与解密版本进行比较,您会注意到原始字符串以'\x00'
开头,并且恢复的版本将删除第一个字节,例如
>>> a = '\x00\xa4\x8aE\xb5,\x1a\x95)Q'
>>> b = k.decrypt(k.encrypt(a, urandom(rand_len)))
>>> a == b
False
>>> len(a)
10
>>> len(b)
9
>>> a
'\x00\xa4\x8aE\xb5,\x1a\x95)Q'
>>> b
'\xa4\x8aE\xb5,\x1a\x95)Q'
你会注意到,除第一个字节外,a和b是相同的。
显然NUL对于C字符串终止很重要,但我很惊讶它以这种方式失败而不是简单地将原始字符串视为空字符串。我想这个库只是跳过任何领先的NUL并用字符串的其余部分加密。