2012-07-13 42 views
4

似乎有使用Python加密包RSA加密/解密的问题:蟒蛇加密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

对我而言看起来不错 – 2012-07-13 07:57:27

回答

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,并用字符串的其余部分进行加密。

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上的数字操作,而不是内部的字节,这意味着前导零将不被考虑。 encryptdecrypt是非常低级的。

对于签署你应该使用Signature包(pycrypto2.5 +),它负责正确填充你的消息。否则你必须自己填充消息。

+0

谢谢! 现在我知道如何解决它! – user1522840 2012-07-13 16:14:01

+0

也注意到,解密crypto时也将字符串视为数字,并忽略第一个'\ x00'。这应该回到解密的字符串。 – user1522840 2012-07-14 11:23:13