2013-01-17 10 views
13

私はPythonクライアントとRubyサーバがデータを暗号化する方法について意見の相違があるのを理解しようとしています。私がRubyコードと私のコードで見る唯一の違いは、初期化ベクトルを指定していないことです。したがって、デフォルトのすべての\ x0に戻ってきます。PyCryptoがデフォルトのIVを使用しないのはなぜですか?

ivなしでPyCryptoをインスタンス化しようとすると、エラー。ここでの例である:

from Crypto.Cipher import AES 
test = "Very, very confidential data" 
key = b'Thirty Two Byte key, made Beef y' 

gryp = AES.new(key, AES.MODE_CBC) 

ドキュメントをWと言う(この例では、本質的にIVを指定せずPyCryptoドキュメントからのサンプルコードである)/ R/IV "それは任意であり、存在しない場合、それはなりTすべてのゼロのデフォルト値が与えられています。しかし、私は "ValueError:IVは16バイト長でなければならない"というエラーを受け取ります。

私はIVを指定することができますが、これは問題以前のものではありませんが、デフォルトを使用できないと思っている場合は、ライブラリを使用している方法が間違っている。

答えて

16

これは、IV、1つを必要とするモードのためのオプションないであるように、AESの実装が変更されたとして、PycryptoのAESのためのクラスのドキュメントでエラーのように見える(つまり、あなたが16のバイトを渡す必要がありますそれがあなたがそれをしたいと思っているならば、自分自身をゼロにする)。

これを参照してくださいbug report for the same issue誰かがIVを指定せず、オンラインドキュメントを検索しました。明示的にIVを必要とする変更があり、本質的に、誰もこれを反映するためにオンラインドキュメントを更新していません。 Pycryptoソースのクラスドキュメントは更新されましたが、これを反映するためにオンラインドキュメントを再生成する必要があります。

元の状態から新しいドキュメント:代わりにIVを指定し、ソース、古いバージョンの

For all other modes, it must be block_size bytes longs. It is optional and when not present it will be given a default value of all zeroes.

更新例の

For all other modes, it must be block_size bytes longs.

は、次のとおりです。

from Crypto.Cipher import AES 
from Crypto import Random 

key = b'Sixteen byte key' 
iv = Random.new().read(AES.block_size) 
cipher = AES.new(key, AES.MODE_CFB, iv) 
msg = iv + cipher.encrypt(b'Attack at dawn') 
3

ここにいくつかの修正を加えて私のために働く実装です:

class AESCipher: 

    def __init__(self, key): 
     self.bs = 32 
     if len(key) >= 32: 
      self.key = key[:32] 
     else: 
      self.key = self._pad(key) 

    def encrypt(self, raw): 
     raw = self._pad(raw) 
     iv = Random.new().read(AES.block_size) 
     cipher = AES.new(self.key, AES.MODE_CBC, iv) 
     return base64.b64encode(iv + cipher.encrypt(raw)) 

    def decrypt(self, enc): 
     enc = base64.b64decode(enc) 
     iv = enc[:AES.block_size] 
     cipher = AES.new(self.key, AES.MODE_CBC, iv) 
     return self._unpad(cipher.decrypt(enc[AES.block_size:])) 

    def _pad(self, s): 
     return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs) 

    def _unpad(self, s): 
     return s[:-ord(s[len(s)-1:])] 
+0

キーを切り捨てるのは悪い考えです。 – cpburnz