2012-07-13 145 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