0

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

ここで、その数値を 16 進文字列として表します。これは機能します。

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

inspect モジュールを使用して、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 オブジェクトを使用して数値を暗号化しようとすると、エラーが発生するのはなぜですか?

入力が int ではなく long 形式であることを期待するのはなぜですか?

4

3 に答える 3

2

rsa.encryptトレースバックは、 long 型の引数が必要であることを明確に示しています。文字列の場合は long 型に変換します。

rsa.encrypt(4L,"")

これは機能し、4Lまだ数値ですが、タイプは long です。

長い質問をする理由は、暗号化を実行するには、パディングを行ってから、パディングされた番号を実行する必要があるためだと思います。この数値は非常に長く、sha1 の場合は 512 の倍数です。したがって、少なくとも 512 int の数値ではニーズを満たすことができません。そんなに長く尋ねられます。そして、検査の結果からわかるように、文字列への型変換のみを行い、int は行いません。したがって、int を渡すとエラーになります。モジュールのソースコードをハッキングする以外に方法はありません。

long の場合、long を返します。たぶん、これを使ってエンコーディングを行うことができます:

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

また、整数をバイトに変更することもできます: rsa.encrypt(input, '')[0].encode('hex'). 入力はstruct.pack('b', 4)です。

于 2013-07-14T17:49:56.450 に答える
1

Python 2.x には 2 種類の整数があります。

  • ローカル プラットフォームのintC 型と一致する型。long精度は制限されていますが、少なくとも 32 ビットです。
  • 無限のlong精度を持つ型。

PyCrypto の RSA キー オブジェクトのencryptandメソッドは、または バイナリ文字列でのみ機能し、 では機能しません。これはPyCrypto の APIに記載されています。decryptlongint

理論的には、 function を使用して整数を必要な型に強制することでコードを修正できますがlong()、コードが安全ではないことに注意してください。

RSA 暗号化は、入力/出力としてOAEP パディングとバイト文字列を使用して実行する必要があります。

于 2013-07-14T18:23:41.747 に答える