2013-02-05 36 views
10

मैं समझने की कोशिश कर रहा हूं कि कैसे एक परियोजना में PyCrypto उपयोग करने के लिए काम करता है लेकिन मैं प्रारंभिक वेक्टर (IV) के महत्व को पूरी तरह समझ नहीं रहा हूं। मैंने पाया है कि मैं स्ट्रिंग को डीकोड करते समय गलत चतुर्थ का उपयोग कर सकता हूं और मुझे अभी भी पहले 16 बाइट्स (ब्लॉक आकार) को छोड़कर संदेश वापस मिल रहा है। क्या मैं बस गलत इस्तेमाल कर रहा हूं या कुछ समझ नहीं रहा हूं?PyCrypto - प्रारंभिक वेक्टर कैसे काम करता है?

यहाँ एक नमूना कोड प्रदर्शित करने के लिए है:

import Crypto 
import Crypto.Random 
from Crypto.Cipher import AES 

def pad_data(data): 
    if len(data) % 16 == 0: 
     return data 
    databytes = bytearray(data) 
    padding_required = 15 - (len(databytes) % 16) 
    databytes.extend(b'\x80') 
    databytes.extend(b'\x00' * padding_required) 
    return bytes(databytes) 

def unpad_data(data): 
    if not data: 
     return data 

    data = data.rstrip(b'\x00') 
    if data[-1] == 128: # b'\x80'[0]: 
     return data[:-1] 
    else: 
     return data 


def generate_aes_key(): 
    rnd = Crypto.Random.OSRNG.posix.new().read(AES.block_size) 
    return rnd 

def encrypt(key, iv, data): 
    aes = AES.new(key, AES.MODE_CBC, iv) 
    data = pad_data(data) 
    return aes.encrypt(data) 

def decrypt(key, iv, data): 
    aes = AES.new(key, AES.MODE_CBC, iv) 
    data = aes.decrypt(data) 
    return unpad_data(data) 

def test_crypto(): 
    key = generate_aes_key() 
    iv = generate_aes_key() # get some random value for IV 
    msg = b"This is some super secret message. Please don't tell anyone about it or I'll have to shoot you." 
    code = encrypt(key, iv, msg) 

    iv = generate_aes_key() # change the IV to something random 

    decoded = decrypt(key, iv, code) 

    print(decoded) 

if __name__ == '__main__': 
    test_crypto() 

मैं अजगर 3.3 का उपयोग कर रहा हूँ।

आउटपुट निष्पादन पर अलग अलग होंगे, लेकिन मैं कुछ इस तरह मिलती है: b"1^,Kp}Vl\x85\x8426M\xd2b\x1aer secret message. Please don't tell anyone about it or I'll have to shoot you."

उत्तर

17

जो व्यवहार आप देखते हैं वह सीबीसी मोड के लिए विशिष्ट है। सीबीसी के साथ, डिक्रिप्शन (विकिपीडिया से) निम्नलिखित तरीके से देखे जा सकते हैं:

CBC decryption

आप देख सकते हैं कि चतुर्थ केवल सादा पाठ के पहले 16 बाइट्स योगदान देता है। यदि IV रिसीवर के पारगमन में होने पर भ्रष्ट हो जाता है, तो सीबीसी अभी भी सभी ब्लॉक को सही तरीके से डिक्रिप्ट करेगा लेकिन पहले वाला। सीबीसी में, IV का उद्देश्य आपको एक ही कुंजी के साथ एक ही संदेश को एन्क्रिप्ट करने में सक्षम बनाता है, और फिर भी हर बार एक पूरी तरह से अलग सिफरटेक्स्ट मिलता है (भले ही संदेश की लंबाई कुछ दे सकती है)।

अन्य मोड कम क्षमा कर रहे हैं। यदि आपको IV गलत लगता है, तो पूरा संदेश डिक्रिप्शन पर गड़बड़ कर दिया जाता है।

CTR mode

+0

ठीक है, मुझे लगता है कि मैं समझता हूं ... मैंने सोचा कि शायद एन्क्रिप्टेड टेक्स्ट केवल पहले ब्लॉक के लिए बदला जाएगा, लेकिन ऐसा लगता है कि यह बाइट्स की पूरी श्रृंखला को प्रभावित करता है। ऐसा लगता है कि भेजने से पहले एवीप्टेड कोड में IV को प्रीपेड करना एक आम प्रथा है, इसलिए मुझे लगता है कि मैं ऐसा करने जा रहा हूं। –

1

PyCrypto के लिए डेवलपर NIST से एईएस सीबीसी मोड के लिए विनिर्देश खींच लिया:

AES Mode_CBC -> संदर्भित NIST 800-38a (The Recommendation for Cipher Mode Operations)

से कि, पृष्ठ 8:

5.3 प्रारंभिक वेक्टर

सीबीसी, सीएफबी, और ओएफबी मोड की एन्क्रिप्शन प्रक्रियाओं में इनपुट में सादे टेक्स्ट के अलावा, प्रारंभिक वेक्टर (IV) नामक डेटा ब्लॉक, आईवी दर्शाया गया है। चतुर्थ का उपयोग किसी संदेश के एन्क्रिप्शन और संदेश के संबंधित डिक्रिप्शन में प्रारंभिक चरण में किया जाता है। चतुर्थ को गुप्त नहीं होना चाहिए; हालांकि, सीबीसी और सीएफबी मोड के लिए, किसी विशेष एन्क्रिप्शन प्रक्रिया के निष्पादन के लिए चौथाई अप्रत्याशित होना चाहिए, और, ओएफबी मोड के लिए, अद्वितीय IVs को एन्क्रिप्शन प्रक्रिया के प्रत्येक निष्पादन के लिए उपयोग किया जाना चाहिए। IVs की पीढ़ी परिशिष्ट सी में चर्चा की है


बात को याद है, आप एक यादृच्छिक चतुर्थ हर बार जब आप एक संदेश लिखें उपयोग करने की आवश्यकता है, इस संदेश के लिए एक 'नमक' इसलिए संदेश अद्वितीय बनाने कहते हैं, ओपन में 'नमक' होने के बावजूद, एईएस एन्क्रिप्शन कुंजी अज्ञात है, तो यह एन्क्रिप्शन तोड़ने में मदद नहीं करेगा। यदि आप यादृच्छिक IV का उपयोग नहीं करते हैं, तो कहें, आप प्रत्येक संदेश, आपके संदेशों को उसी 16 बाइट्स का उपयोग करते हैं, यदि आप स्वयं को दोहराते हैं, तो तार के समान ही दिखाई देगा और आप आवृत्ति और/या रीप्ले हमलों के अधीन हो सकते हैं।

स्थिर बनाम यादृच्छिक IVs के परिणामों के लिए एक परीक्षण:

def test_crypto(): 
    print("Same IVs same key:") 
    key = generate_aes_key() 
    iv = b"123456789" 
    msg = b"This is some super secret message. Please don't tell anyone about it or I'll have to shoot you." 
    code = encrypt(key, iv, msg) 
    print(code.encode('hex')) 
    decoded = decrypt(key, iv, code) 
    print(decoded) 

    code = encrypt(key, iv, msg) 
    print(code.encode('hex')) 
    decoded = decrypt(key, iv, code) 
    print(decoded) 

    print("Different IVs same key:") 
    iv = generate_aes_key() 
    code = encrypt(key, iv, msg) 
    print(code.encode('hex')) 
    decoded = decrypt(key, iv, code) 
    print(decoded) 

    iv = generate_aes_key() 
    code = encrypt(key, iv, msg) 
    print(code.encode('hex')) 
    decoded = decrypt(key, iv, code) 
    print(decoded) 

आशा इस मदद करता है!

+0

कि इस सवाल का जवाब स्पष्ट नहीं होता क्यों चतुर्थ, अगर यह सीबीसी में हर ब्लॉक के डिक्रिप्शन को प्रभावित करती है: उदाहरण के लिए, जहां अस्थायी रूप सेचतुर्थ के लगभग एक ही अर्थ लेता है के लिए सीटीआर मोड ले लो मोड, केवल पहले ब्लॉक के डिक्रिप्शन को प्रभावित किया। – Patashu

+0

'विशेषताइरर: 'बाइट्स' ऑब्जेक्ट में कोई विशेषता नहीं है 'एनकोड' 'प्रिंट के साथ एन्क्रिप्टेड कोड को प्रिंट करने का प्रयास करते समय मुझे मिलता है (code.encode (' hex ')) –

+0

दोहराए गए हमलों के बारे में नोट के लिए धन्यवाद ... मैं प्रत्येक संदेश पर एक यादृच्छिक चतुर्थ का उपयोग करने जा रहा हूं और इसे एन्क्रिप्टेड कोड में प्रीपेड कर रहा हूं। –