2013-07-14 64 views
0

我想使用RSA加密整數。Python 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 

使用檢查模塊我檢查了RSA對象的加密函數的源代碼,它說它可以加密字符串或整數純文本:

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對象加密一個數字時,它會給出一個錯誤?

爲什麼它預計投入是長期的格式,而不是詮釋?

回答

2

回溯講述清楚rsa.encrypt要長類型的參數。如果它是一個字符串,它會將它變成長整型。

rsa.encrypt(4L,"") 

這將工作和4L仍然是一個數字,但它的類型是長期的。

我想原因要問長就是要執行加密,你必須做一些填充,然後在填充數執行。這個數字非常長,對於sha1來說,它是512的倍數。所以對於一個數字,至少有512個int不能滿足需要。問了很長時間。你可以從你的檢查結果看到,它只對字符串進行類型轉換,沒有int。所以如果你傳遞一個int,那就錯了。除了黑客模塊的源代碼之外,您沒有其他方法。

長期以來,它返回一個長。也許你可以用這個做編碼:

hex(rsa.encrypt(4L, '')[0]).rstrip('L').lstrip(0x) 
'31bf11047cbe9115541e29acb5046d98f2a9bdc44d4768668e9119f8eca24bf24dfc4ac070950734e819675f93e1809859b750df63e8bc71afc7c83edfc6d2f59f495c8e378e0633f07e21672a7e862cfa77a6aede48075dec0cd2b1d8c016dade779f1ea8bd9ffa8ef314c4e391b0f5860cf06cb0f991d2875c49722e98b94f' 

您也可以整數更改爲字節:rsa.encrypt(input, '')[0].encode('hex')。輸入是struct.pack('b', 4)

+0

是的,我知道它期望long類型的參數。我的問題是,爲什麼期望很長而不是整數?其次,我不提供輸入的原因是因爲你不能在長對象上調用encode('hex')。它會導致錯誤。而我正在使用的程序,它將始終調用rsa.encrypt的輸出上的encode('hex')方法。這就是爲什麼,我需要一種方式來發送我的輸入作爲一個整數。 Will \ x04與4號相同嗎? –

+0

答覆已更新。請檢查。@ NeonFlash – zhangyangyu

+0

感謝您的更新。加密腳本的源代碼已寫入。它要求我輸入一個將被加密的輸入。現在,源代碼正在使用編碼('十六進制')加密的結果,正如我在代碼片段中提到的那樣。正如我所說的,我需要一種方法來發送一個數字作爲加密腳本的輸入,同時它不應該是長格式。這是因爲加密腳本在加密輸出上使用了編碼('十六進制')。如果您輸入的時間太長,則會發生錯誤。我的問題是,我如何以字符串格式輸入數字? –

1

的Python 2.x中有兩種類型的整數:

  • int類型,其中地方平臺上的C類long匹配。精度是有限的,但至少是32位。
  • long類型,其具有無限精度。

在PyCrypto RSA密鑰對象的encryptdecrypt方法只適用於long或二進制字符串,不int。這在PyCrypto's API中有記錄。

從理論上講,您可以通過使用函數long()將整數強制爲所需類型來修復代碼,但值得指出的是代碼不安全。

RSA加密應該使用OAEP padding和字節字符串作爲輸入/輸出。

+0

是的,我可以提供我的輸入。但問題是這樣的:如果輸入格式爲長格式,則rsa.encrypt(input,「」)[0] .encode('hex')將會出錯,因爲您無法在長對象上調用encode方法。這就是自定義加密腳本的編寫方式。所以,將我的輸入作爲數字傳遞給腳本的唯一方式是字符串格式。所以,我想知道如何將自定義加密腳本的輸入作爲字符串格式的數字輸入?我使用\ x04發送數字4作爲輸入,其他方法?如果我說「4」,那是一樣的嗎? –

+0

@ neon-flash關於十六進制(rsa.encrypt(long(input),「」)[0])[2:]?再次,這根本不安全... – SquareRootOfTwentyThree

+0

我無法修改此加密服務的源代碼,正如我之前所說的。它已經在另一臺機器上運行了,我只能給它一個輸入。由於它希望輸入是字符串格式,所以我只想知道發送一個數字作爲輸入的方式。我可以將它打包爲一個字節併發送。 –