5

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)
4

2 回答 2

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+),它负责正确填充您的消息。否则你必须自己填写你的信息。

于 2012-07-13T08:05:04.993 回答
1

\x00'对于以 NUL ( )开头的输入字符串,每次解密失败都会发生。如果您将原始字符串与解密版本进行比较,您会注意到原始字符串以开头'\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 并使用字符串的其余部分进行加密。

于 2012-07-13T08:00:58.820 回答