2013-01-17 48 views
13

मैं यह पता लगाने की कोशिश कर रहा हूं कि क्यों मेरे पायथन क्लाइंट और रूबी सर्वर को डेटा एन्क्रिप्ट करने के बारे में असहमति है। रूबी कोड और मेरे कोड में केवल एक ही अंतर यह है कि वे प्रारंभिक वेक्टर निर्दिष्ट नहीं कर रहे हैं, इसलिए यह सभी \ x0 केक्यों PyCrypto डिफ़ॉल्ट चतुर्थ का उपयोग नहीं करता है?

के डिफ़ॉल्ट पर वापस आ रहा है जब मैं 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 का कहना है (इस उदाहरण अनिवार्य रूप से चतुर्थ निर्दिष्ट किए बिना PyCrypto डॉक्स से उदाहरण कोड है)/आर/चतुर्थ "यह वैकल्पिक है और जब यह मौजूद नहीं होगा टी सभी शून्यों का डिफ़ॉल्ट मान दिया गया। " हालांकि मुझे त्रुटि मिलती है "ValueError: IV 16 बाइट लंबा होना चाहिए"।

तो मैं IV को निर्दिष्ट कर सकता हूं, यह समस्या पूर्व नहीं है, लेकिन मैं यह समझने की कोशिश कर रहा हूं कि अगर यह सोचता है कि यह डिफ़ॉल्ट का उपयोग नहीं कर सकता है, तो पुस्तकालय का उपयोग करने के तरीके में कुछ और गलत है ।

उत्तर

16

इस रूप में एईएस कार्यान्वयन ताकि चतुर्थ उन मोड की आवश्यकता है कि एक (यानी आप के 16 बाइट्स से पारित करना होगा के लिए वैकल्पिक नहीं है बदल दिया गया है, Pycrypto के AES के लिए वर्ग दस्तावेज में एक त्रुटि हो गया लगता है खुद को शून्य, अगर ऐसा है कि आप इसे कैसे करना चाहते हैं)।

यह bug report for the same issue देखें जहां किसी ने IV IV निर्दिष्ट नहीं किया था और ऑनलाइन दस्तावेज़ों को देखा था। एक बदलाव था जिसमें स्पष्ट रूप से IV की आवश्यकता होती है और अनिवार्य रूप से, किसी ने इसे प्रदर्शित करने के लिए ऑनलाइन दस्तावेज़ अपडेट नहीं किए हैं। Pycrypto स्रोत में वर्ग दस्तावेज़ अद्यतन किया गया था, लेकिन ऑनलाइन प्रलेखन को इसे प्रतिबिंबित करने के लिए पुन: उत्पन्न करने की आवश्यकता है।

स्रोत राज्यों से नई प्रलेखन:

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

पुराने संस्करण के

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.

स्रोत है, जो iv निर्दिष्ट करता है में अद्यतन उदाहरण के बजाय

, है:

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