2009-03-02 13 views
26

का उपयोग करके मैं एस्मानेड के साथ काम कर रहा सरल एन्क्रिप्शन/डिक्रिप्शन प्राप्त करने का प्रयास कर रहा हूं, लेकिन डिक्रिप्शन स्ट्रीम को बंद करने का प्रयास करते समय मुझे अपवाद मिल रहा है। यहां स्ट्रिंग एन्क्रिप्टेड हो जाती है और सही ढंग से डिक्रिप्ट हो जाती है, और फिर मुझे क्रिप्टोग्राफिक एक्सेप्शन मिलता है "कंसोल के बाद पैडिंग अमान्य था और हटाया नहीं जा सकता"। राइटलाइन सही स्ट्रिंग को प्रिंट करता है।"पैडिंग अमान्य है और इसे हटाया नहीं जा सकता" AesManaged

कोई विचार?

MemoryStream ms = new MemoryStream(); 
byte[] rawPlaintext = Encoding.Unicode.GetBytes("This is annoying!"); 

using (Aes aes = new AesManaged()) 
{ 
    aes.Padding = PaddingMode.PKCS7; 
    aes.Key = new byte[128/8]; 
    aes.IV = new byte[128/8]; 

    using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), 
              CryptoStreamMode.Write)) 
    { 
    cs.Write(rawPlaintext, 0, rawPlaintext.Length); 
    cs.FlushFinalBlock(); 
    } 

    ms = new MemoryStream(ms.GetBuffer()); 
    using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), 
              CryptoStreamMode.Read)) 
    { 
    byte[] rawData = new byte[rawPlaintext.Length]; 
    int len = cs.Read(rawData, 0, rawPlaintext.Length); 
    string s = Encoding.Unicode.GetString(rawData); 
    Console.WriteLine(s); 
    } 
} 

उत्तर

44

चाल MemoryStream.ToArray() का उपयोग करना है। मैंने आपके कोड को भी बदल दिया ताकि यह एन्क्रिप्टिंग और डिक्रिप्टिंग दोनों में लिखने के लिए CryptoStream का उपयोग कर सके। और आपको CryptoStream.FlushFinalBlock() को स्पष्ट रूप से कॉल करने की आवश्यकता नहीं है, क्योंकि आपके पास using() कथन में है, और यह फ्लश Dispose() पर होगा। मेरे लिए निम्नलिखित काम करता है।

byte[] rawPlaintext = System.Text.Encoding.Unicode.GetBytes("This is all clear now!"); 

using (Aes aes = new AesManaged()) 
{ 
    aes.Padding = PaddingMode.PKCS7; 
    aes.KeySize = 128;   // in bits 
    aes.Key = new byte[128/8]; // 16 bytes for 128 bit encryption 
    aes.IV = new byte[128/8]; // AES needs a 16-byte IV 
    // Should set Key and IV here. Good approach: derive them from 
    // a password via Cryptography.Rfc2898DeriveBytes 
    byte[] cipherText= null; 
    byte[] plainText= null; 

    using (MemoryStream ms = new MemoryStream()) 
    { 
     using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) 
     { 
      cs.Write(rawPlaintext, 0, rawPlaintext.Length); 
     } 

     cipherText= ms.ToArray(); 
    } 


    using (MemoryStream ms = new MemoryStream()) 
    { 
     using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write)) 
     { 
      cs.Write(cipherText, 0, cipherText.Length); 
     } 

     plainText = ms.ToArray(); 
    } 
    string s = System.Text.Encoding.Unicode.GetString(plainText); 
    Console.WriteLine(s); 
} 

इसके अलावा, मैं तुम्हें पता है कि आप स्पष्ट रूप AesManaged उदाहरण के Mode सेट करना चाहते हैं जाएगा लगता है, और System.Security.Cryptography.Rfc2898DeriveBytes का उपयोग कुंजी और एक पासवर्ड और नमक से चतुर्थ प्राप्त करने के लिए।

यह भी देखें:
- AesManaged

+4

मुझे एक ही समस्या थी, लेकिन रिजेंडेल मैनेज्ड (सममित) का उपयोग करके और यह नहीं पता था कि क्या हो रहा था। यह पता चला है कि 'MemoryStream.GetBuffer() 'डेटा का एक * unflushed * संस्करण प्राप्त कर रहा था, और डेटा के अधिकांश अंतिम ब्लॉक शून्य थे, जो मेरे पैडिंग के साथ गड़बड़ कर रहा था। 'मेमोरीस्ट्रीम। टोएरे()' असली सरणी प्राप्त करता है। इस समाधान के लिए बहुत धन्यवाद! – Codesleuth

+0

यह अब तक का सबसे अच्छा/छोटा कार्यान्वयन है जिसे मैंने देखा है। – tmanthey

+1

'निपटान' पर अच्छी कॉल। मैं CryptoStream का निपटान करने से पहले 'ms.ToArray()' को बुला रहा था। उपयोग के बाहर उस रेखा को आगे बढ़ाना मेरे लिए तय है। – cadrell0

1

बाइट [] rawData = नए बाइट [rawPlaintext.Length];

आपको बफर की लंबाई को पढ़ने की आवश्यकता है, जिसमें शायद आवश्यक पैडिंग (आईआईआरसी, कुछ साल हो) शामिल है।

21

यह अपवाद एन्क्रिप्शन अनेक मानदंड से किसी एक की एक बेमेल की वजह से हो सकता है।

मैंने एन्क्रिप्ट/डिक्रिप्ट विधियों में उपयोग किए गए सभी मानकों का पता लगाने के लिए Security.Cryptography.Debug इंटरफ़ेस का उपयोग किया।

अंत में मुझे पता चला कि मेरी समस्या मैं Key की स्थापना एक यादृच्छिक कुंजी पुनर्जीवित करने के लिए वर्ग पैदा कर रहा और महत्वपूर्ण यह है कि मैं शुरू में स्थापित किया गया था का उपयोग नहीं करने के बाद KeySize गुण सेट है कि था।

+4

मेरी समस्या कुंजी सेट करने के बाद KeySize भी सेट कर रही थी, धन्यवाद! –

+2

+1 आपको बहुत धन्यवाद, अगर मैं कर सकता तो मैं आपको 100 बार वोट दूंगा। मैंने एक दिन में यह पता लगाने की कोशिश की है कि मैं ठीक से डिक्रिप्ट क्यों नहीं कर सका और यह पता चला कि मैं कोड में कुंजी के बाद कुंजी आकार सेट कर रहा था। – LeopardSkinPillBoxHat

+0

धन्यवाद, इसने मेरी समस्या हल की –

1

कोई भी उत्तर नहीं दिया, वास्तव में MemoryStream.GetBuffer आवंटित बफर लौटाता है, न कि इस बफर में वास्तविक डेटा। इस मामले में यह 256-बाइट बफर देता है, जबकि इसमें केवल 32 बाइट एन्क्रिप्टेड डेटा होते हैं।

संबंधित मुद्दे

 संबंधित मुद्दे