पैडिंग अमान्य है और उसे हटाया नहीं जा सकता है?


126

मैंने ऑनलाइन देखा है कि इस अपवाद का मेरे कार्यक्रम के संबंध में क्या मतलब है, लेकिन इसका कोई समाधान या कारण नहीं मिल सकता है कि यह मेरे विशिष्ट कार्यक्रम के लिए क्यों हो रहा है। मैं Rijndael एल्गोरिथ्म का उपयोग कर एक XmlDocument एन्क्रिप्ट करने और डिक्रिप्ट करने के लिए अपने msdn प्रदान किए गए उदाहरण का उपयोग कर रहा हूं। एन्क्रिप्शन ठीक काम करता है, लेकिन जब मैं डिक्रिप्ट करने की कोशिश करता हूं, तो मुझे निम्न अपवाद मिलते हैं:

पैडिंग अमान्य है और उसे हटाया नहीं जा सकता

क्या कोई मुझे बता सकता है कि मैं इस मुद्दे को हल करने के लिए क्या कर सकता हूं? नीचे मेरा कोड है जहां मुझे कुंजी और अन्य डेटा मिलते हैं। यदि क्रिप्टोकरंसी गलत है, तो यह डिक्रिप्ट विधि को कॉल करेगा, जहां अपवाद होता है:

public void Cryptography(XmlDocument doc, bool cryptographyMode)
{
    RijndaelManaged key = null;
    try
    {
    // Create a new Rijndael key.
    key = new RijndaelManaged();
    const string passwordBytes = "Password1234"; //password here 

    byte[] saltBytes = Encoding.UTF8.GetBytes("SaltBytes");
    Rfc2898DeriveBytes p = new Rfc2898DeriveBytes(passwordBytes, saltBytes);
    // sizes are devided by 8 because [ 1 byte = 8 bits ] 
    key.IV = p.GetBytes(key.BlockSize/8);
    key.Key = p.GetBytes(key.KeySize/8);

    if (cryptographyMode)
    {
        Ecrypt(doc, "Content", key);
    }
    else
    {
        Decrypt(doc, key);
    }

    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
    finally
    {
    // Clear the key.
    if (key != null)
    {
        key.Clear();
    }
    }

}

private void Decrypt(XmlDocument doc, SymmetricAlgorithm alg)
{
    // Check the arguments.  
    if (doc == null)
    throw new ArgumentNullException("Doc");
    if (alg == null)
    throw new ArgumentNullException("alg");

    // Find the EncryptedData element in the XmlDocument.
    XmlElement encryptedElement = doc.GetElementsByTagName("EncryptedData")[0] as XmlElement;

    // If the EncryptedData element was not found, throw an exception.
    if (encryptedElement == null)
    {
    throw new XmlException("The EncryptedData element was not found.");
    }


    // Create an EncryptedData object and populate it.
    EncryptedData edElement = new EncryptedData();
    edElement.LoadXml(encryptedElement);

    // Create a new EncryptedXml object.
    EncryptedXml exml = new EncryptedXml();


    // Decrypt the element using the symmetric key.
    byte[] rgbOutput = exml.DecryptData(edElement, alg); <----  I GET THE EXCEPTION HERE
    // Replace the encryptedData element with the plaintext XML element.
    exml.ReplaceData(encryptedElement, rgbOutput);

}

12
क्या आप इसे एन्क्रिप्शन और डिक्रिप्शन दोनों पर समान होने के लिए पैडिंग मोड को स्पष्ट रूप से सेट करके इंडेंटिकल होने का प्रयास कर सकते हैं। उदाहरण के लिए: alg.Padding = PaddingMode.NONE;
नेटसक्वायरेल

एनक्रिप्ट () विधि क्या दिखती है?
csharptest.net

1
धन्यवाद दोस्तों कि काम किया।
ब्राउन लव

2
@NetSquirrel: PaddingMode.NONE के लिए अनुस्मारक के लिए धन्यवाद। यह मुझे इस त्रुटि से (एक और एक को) ... जावा और सी # दोनों में एईएस कर रहा है, और अब पता नहीं क्यों सी # जावा पैडिंग के बारे में शिकायत करता है, हालांकि दोनों पीकेसीएस का उपयोग करते हैं # 7
होएंग लॉन्ग

जवाबों:


81

Rijndael / AES एक ब्लॉक साइफ़र है। यह 128 बिट (16 वर्ण) ब्लॉक में डेटा को एन्क्रिप्ट करता है। क्रिप्टोग्राफ़िक पैडिंग का उपयोग यह सुनिश्चित करने के लिए किया जाता है कि संदेश का अंतिम ब्लॉक हमेशा सही आकार का हो।

आपकी डिक्रिप्शन विधि यह उम्मीद कर रही है कि इसका डिफ़ॉल्ट पैडिंग जो भी हो, और यह नहीं मिल रहा है। जैसा कि @NetSquirrel कहता है, आपको एन्क्रिप्शन और डिक्रिप्शन दोनों के लिए स्पष्ट रूप से पैडिंग सेट करने की आवश्यकता है। जब तक आपके पास अन्यथा करने का कोई कारण नहीं है, PKCS # 7 पैडिंग का उपयोग करें।


7
कैसे स्पष्ट रूप से पैडिंग सेट करने के लिए ??
अहमद हजजर

7
धन्यवाद, मैंने इसे rj.Padding = PaddingMode.none पाया; :)
अहमद हजज़ार

7
@ अहमदाबादमाजर में कोई भी गद्दी सुरक्षा निहितार्थ नहीं है, इसका उपयोग न करें।
देवयानफैन

1
नमस्ते, मैंने स्पष्ट रूप से पैडिंग सेट किया, लेकिन काम नहीं किया। मुझे नहीं पता कि मैंने क्या कदम उठाए। कृपया मदद कीजिए। alg.Padding = PaddingMode.PKCS7;
जॉनी

21
मुझे एहसास है कि यह एक पुराना धागा है। लेकिन, आने वालों के लिए, सुनिश्चित करें कि डेटा एन्क्रिप्ट करते समय आप अंतिम ब्लॉक को फ्लश करते हैं।
मार्कस

53

सुनिश्चित करें कि आप जिन कुंजियों का उपयोग एन्क्रिप्ट करने के लिए कर रहे हैं और डिक्रिप्ट कर रहे हैं एक ही । पैडिंग विधि भले ही स्पष्ट रूप से सेट न हो फिर भी उचित डिक्रिप्शन / एन्क्रिप्शन के लिए अनुमति देनी चाहिए (यदि सेट नहीं है तो वे समान होंगे)। लेकिन अगर किसी कारण से आप एन्क्रिप्शन के लिए इस्तेमाल की तुलना में डिक्रिप्शन के लिए चाबियों का एक अलग सेट का उपयोग कर रहे आप होगा इस त्रुटि मिलती है:

पैडिंग अमान्य है और उसे हटाया नहीं जा सकता

यदि आप कुछ एल्गोरिथ्म का उपयोग गतिशील रूप से कुंजी उत्पन्न करने के लिए कर रहे हैं जो काम नहीं करेगा। उन्हें एन्क्रिप्शन और डिक्रिप्शन दोनों के लिए समान होना चाहिए। इन सामानों के निर्माण में किसी भी हाथ की एन्क्रिप्शन / डिक्रिप्शन प्रक्रिया को रोकने के लिए, कॉल करने वाले के पास एन्क्रिप्शन पद्धति वर्ग के निर्माण में कुंजी प्रदान करने का एक सामान्य तरीका है। यह हाथ (एन्क्रिप्ट करने और डेटा decrypting) पर काम पर केंद्रित है और आवश्यकता है ivऔरkey फोन करने वाले के द्वारा आपूर्ति किया जाना है।


यह टिप बहुत उपयोगी थी, क्योंकि, कभी-कभी चाबियाँ app.config पर संग्रहीत होती हैं और हमें हमेशा यह सुनिश्चित करना चाहिए कि एन्क्रिप्ट करने के लिए उपयोग की जाने वाली चाबियां डिक्रिप्ट करने के लिए उपयोग की जाती हैं।
मेरियो मेयरेल्स

@atconway क्या आप मेरे प्रश्न पर एक नज़र रखना चाहेंगे? मेरे पास एक समान मुद्दा है लेकिन C ++ / CLI में: stackoverflow.com/questions/57139447/…
सिंपल

1
मेरा सुझाव है कि दिन-प्रतिदिन के उपयोग में, यह संभवतः सबसे अधिक संभावित कारण है कि लोग इस त्रुटि का सामना करेंगे। खासकर यदि आप पैडिंग सेटिंग में गड़बड़ी नहीं कर रहे हैं।
डैन

28

खोज करने वाले लोगों के लाभ के लिए, यह डिक्रिप्ट किए जा रहे इनपुट की जाँच के लायक हो सकता है। मेरे मामले में, डिक्रिप्शन के लिए भेजी जा रही जानकारी (गलत तरीके से) एक खाली स्ट्रिंग के रूप में जा रही थी। इसका परिणाम गद्दी त्रुटि के रूप में सामने आया।

यह रोससम के उत्तर से संबंधित हो सकता है, लेकिन यह ध्यान देने योग्य है।


मैं सहमत हूं, मेरे साथ भी ऐसा ही हुआ है, इनपुट की जांच की जा रही है और अन्य जांच कर रहे हैं। मैं 1 से अधिक बाइट प्राप्त कर रहा था, जो मैंने एनकैप्ड किया ...
एंड्रिया एंटोनजेली

एक खाली तार मेरे लिए भी अपराधी था।
डॉट

मेरा मामला यह था कि पासफ़्रेज़ सेट नहीं किया गया था (हाँ मुझे पता है), लेकिन यह जवाब मुझे सही दिशा में ले गया।
जिम

2
मेरा मुद्दा यह था कि डिक्रिप्ट किए जाने वाले स्ट्रिंग को डिक्रिप्ट करने से पहले मुझे निचले मामले में बदल दिया जा रहा था। मैं गद्दी और सिपहसालारों और उस सभी सामान के साथ जुनून सवार था, लेकिन यह सिर्फ खराब इनपुट था। कभी-कभी आपको बस एक कदम वापस लेने की आवश्यकता होती है!
टॉम जेरकेन

15

यदि एन्कोडिंग और डिकोडिंग के लिए समान कुंजी और इनिशियलाइज़ेशन वेक्टर का उपयोग किया जाता है, तो यह समस्या डेटा डिकोडिंग से नहीं, बल्कि डेटा एन्कोडिंग से आती है।

CryptoStream ऑब्जेक्ट पर लिखें विधि को कॉल करने के बाद, आपको हमेशा बंद विधि से पहले FlushFinalBlock विधि को कॉल करना होगा।

CDNoStream.FlushFinalBlock पद्धति पर MSDN का दस्तावेज़ीकरण कहता है:
" क्लोज़ विधि को कॉल करने पर FlushFinalBlock ... "
https://msdn.microsoft.com/en-US/library/system.security_ryptec.cryptostream.flushfinalblock(v=vsv .110) .aspx
यह गलत है। क्लोज विधि को कॉल करना क्रिप्टोकरंसी और आउटपुट स्ट्रीम को बंद कर देता है।
यदि आप डेटा को एन्क्रिप्ट किए जाने के बाद बंद करने से पहले FlushFinalBlock को कॉल नहीं करते हैं, तो डेटा को डिक्रिप्ट करते समय, आपके CryptoStream ऑब्जेक्ट पर Read या CopyTo विधि का कॉल CryptographicException अपवाद को बढ़ाएगा (संदेश: "पैडिंग अमान्य है और हटाया नहीं जा सकता")।

यह शायद सभी एन्क्रिप्शन एल्गोरिदम के लिए सच है जो SymmetricAlgorithm (Aes, DES, RC2, Rijndael, TripleDES) से लिया गया है, हालांकि मैंने अभी सत्यापित किया है कि आउटपुट स्ट्रीम के रूप में AesManaged और एक MemoryStream।

इसलिए, यदि आपको डिक्रिप्शन पर यह क्रिप्टोग्राफ़िक अपवाद अपवाद प्राप्त होता है, तो अपने डेटा को एन्क्रिप्ट करने के लिए लिखे जाने के बाद अपनी आउटपुट स्ट्रीम लंबाई संपत्ति मूल्य पढ़ें, फिर फ्लश फ़िनलब्लॉक पर कॉल करें और फिर से इसके मूल्य को पढ़ें। यदि यह बदल गया है, तो आप जानते हैं कि FlushFinalBlock कॉल करना वैकल्पिक नहीं है।

और आपको प्रोग्रामिक रूप से कोई पेडिंग करने की आवश्यकता नहीं है, या कोई अन्य पेडिंग प्रॉपर्टी वैल्यू चुनें। पैडिंग फ्लशफाइनलब्लॉक विधि काम है।

.........

केविन के लिए अतिरिक्त टिप्पणी:

हां, CryptoStream बंद करने से पहले FlushFinalBlock को कॉल करता है, लेकिन यह बहुत देर हो चुकी है: जब CryptoStream बंद विधि को कॉल किया जाता है, तो आउटपुट स्ट्रीम भी बंद हो जाती है।

यदि आपकी आउटपुट स्ट्रीम एक मेमोरीस्ट्रीम है, तो आप इसके बंद होने के बाद इसके डेटा को नहीं पढ़ सकते हैं। इसलिए आपको MemoryStream पर लिखे एन्क्रिप्टेड डेटा का उपयोग करने से पहले अपने CryptoStream पर FlushFinalBlock को कॉल करना होगा।

यदि आपका आउटपुट स्ट्रीम एक फाइलस्ट्रीम है, तो चीजें खराब हो जाती हैं क्योंकि लेखन बफर हो जाता है। परिणाम अंतिम लिखित बाइट्स है अगर आप फाइलस्ट्रीम पर फ्लश को कॉल करने से पहले आउटपुट स्ट्रीम को बंद करते हैं तो फाइल को नहीं लिखा जा सकता है। इसलिए CryptoStream पर बंद होने से पहले आपको पहले FlushFinalBlock को अपने CryptoStream पर कॉल करना होगा, फिर अपने FileStream पर Flush को कॉल करें।


1
आप क्यों कहते हैं कि यह गलत है? Stream.Close()कॉल के लिए कोड this.Dispose(true)। के लिए कोड CryptoStream.Dispose(bool)है:if (disposing) { if (!this._finalBlockTransformed) { this.FlushFinalBlock(); } this._stream.Close(); }
केविन डॉयन

1
इससे मेरी समस्या हल हो गई। मैं क्रिप्टोकरंसीज को सही तरीके से डिस्पोज़ कर रहा था, लेकिन डिस्पोज़ कॉल "बहुत देर से" हो रही थी, जैसा कि आप कहते हैं। यह "अमान्य पैडिंग" त्रुटि के रूप में वर्णित है। CryptoStream.FlushFinalBlock () जोड़कर, अमान्य पेडिंग त्रुटि को हल कर दिया गया था। धन्यवाद!
डैनियल लैम्बर्ट

14

लड़ाई का एक समय, मैंने आखिरकार समस्या को हल कर दिया।
(नोट: मैं मानक एईएस का उपयोग सममित एल्गोरिथ्म के रूप में करता हूं। यह उत्तर सभी के लिए उपयुक्त नहीं हो सकता है।)

  1. एल्गोरिथ्म वर्ग बदलें। RijndaelManagedवर्ग को बदलेंAESManaged एक में ।
  2. KeySizeएल्गोरिथ्म वर्ग के स्पष्ट रूप से सेट न करें , उन्हें डिफ़ॉल्ट रूप से छोड़ दिया।
    (यह बहुत महत्वपूर्ण कदम है। मुझे लगता है कि KeySize संपत्ति में एक बग है।)

यहां एक सूची दी गई है जिसे आप जांचना चाहते हैं कि कौन सा तर्क आपको याद हो सकता है:

  • कुंजी
    (बाइट सरणी, लंबाई अलग-अलग कुंजी आकार के लिए 16, 24, 32 बाइट में से एक होनी चाहिए।)
  • IV
    (बाइट सरणी, 16 बाइट्स)
  • सिफरमोड
    (सीबीसी, सीएफबी, सीटीएस, ईसीबी, ओएफबी में से एक)
  • PaddingMode
    ( ANSIX923 में से एक, ISO10126, कोई नहीं, PKCS7, Zeros)

3
स्पष्ट रूप से सेट नहीं KeySizeकरना मेरे लिए सीधे तय है। ओह .NET के quirks :-(
जॉन

ध्यान दें कि यह .NET फ्रेमवर्क में ही एक प्रतिगमन प्रतीत होता है। मेरे पास कोड है जो RijndaelManaged के साथ काम करता था, लेकिन उसने काम करना बंद कर दिया, और बस इसे AesManaged / AesCryptoServiceProvider में बदलकर, यह फिर से काम करता है। मेरे पास कोई कोड भी स्पष्ट रूप से KeySize सेट नहीं था। इसलिए यदि आप इसे काट रहे हैं, तो बेहतर महसूस करें - गलती आपके साथ नहीं, बल्कि .NET फ्रेमवर्क के साथ हो सकती है।
उस्सस

6

मेरा मुद्दा यह था कि एन्क्रिप्ट का पासप्रैस डिक्रिप्ट के पासप्रेज से मेल नहीं खाता था ... इसलिए इस त्रुटि को फेंक दिया .. थोड़ा भ्रामक।


वास्तव में यह सच है कि हम Encrypt और Decrypt के लिए PaddingMode.PKCS7 का उपयोग करते हैं लेकिन मुझे वही त्रुटि संदेश मिला। इसके अलावा हमारे पास विभिन्न प्रमुख मूल्यों के साथ स्टेज और देव वातावरण है। जब मैंने उचित-विशिष्ट का उपयोग किया - कुंजी इस अपवाद को हल किया गया था ...
प्रमुख

यद्यपि उपरोक्त सभी उत्तर अच्छे हैं और आपको एन्क्रिप्ट और डिक्रिप्ट के लिए एक ही पैडिंग का उपयोग करना चाहिए (कोई भी अनुशंसित नहीं है!) वास्तव में यह उत्तर भी सही हो सकता है। जब मैंने उचित-विशिष्ट प्रवर्तन का उपयोग किया, तो अपवाद "System.Security.Cryptography.CryptographicException: Padding अमान्य है और इसे हटाया नहीं जा सकता है।" हल हो गया था। तो हाँ यह भ्रामक हो सकता है।
प्रमुख

यदि "पासप्रेज़" द्वारा आप एन्क्रिप्ट करने / डिक्रिप्ट करने के सही मूल्य (गलत कुंजी का उपयोग करने के साथ कोई समस्या नहीं) के बारे में बात कर रहे हैं, तो हाँ, यह मेरी समस्या थी। मेरा मामला यह था कि मूल एन्क्रिप्टेड मूल्य मेरे डेटाबेस टेबल फ़ील्ड की अनुमति से अधिक लंबा था, इसलिए मुझे इसे साकार किए बिना फिट करने के लिए छोटा किया जा रहा था। फिर जब उस काटे गए मूल्य को डिक्रिप्ट किया गया तो यह अपवाद फेंक दिया गया।
डेविड गुंडरसन जूल

2

मेरा निश्चित समाधान यह था कि मैंने अनजाने में एन्क्रिप्शन और डिक्रिप्शन विधियों के लिए अलग-अलग चाबियाँ लागू की थीं।


1

डिक्रिप्ट विधि में अन-एन्क्रिप्टेड फ़ाइल पथ को पास करने का प्रयास करते समय मुझे यह त्रुटि आई। समाधान यह जांचना था कि डिक्रिप्ट करने के प्रयास से पहले पारित फ़ाइल एन्क्रिप्टेड है या नहीं

if (Sec.IsFileEncrypted(e.File.FullName))
{
    var stream = Sec.Decrypt(e.File.FullName);
} 
else
{
    // non-encrypted scenario  
}

1
मैं इस समाधान की वैधता के बारे में किसी भी हिट एंड रन कायर को चुनौती देता हूं।
उपयोगीबाई

+1 क्योंकि यह अपवाद तब उठाया जाता है जब आप दो बार डिक्रिप्ट करते हैं या आप एन्क्रिप्ट नहीं किए गए कुछ को डिक्रिप्ट करते हैं। इसलिए मैंने इस जवाब को पढ़ा "क्या आप सुनिश्चित हैं कि डेटा वास्तव में एन्क्रिप्टेड है?"।
गेरार्डो ग्रिग्नोली

0

एक और परिदृश्य, खोज करने वाले लोगों के लाभ के लिए फिर से।

मेरे लिए यह त्रुटि डिस्पोज़ () पद्धति के दौरान हुई थी जो एन्क्रिप्शन से असंबंधित पिछली त्रुटि का सामना करती है।

एक बार अन्य घटक तय हो जाने के बाद, यह अपवाद चला गया।


3
एन्क्रिप्शन में पिछली त्रुटि क्या असंबंधित थी?
NStuke

0

जब मुझे मैन्युअल रूप से फ़ाइल (नोटपैड का उपयोग करके) में एन्क्रिप्टेड स्ट्रिंग्स को संपादित करना होगा, तो मुझे इस पैडिंग त्रुटि का सामना करना पड़ा, क्योंकि मैं यह परीक्षण करना चाहता था कि यदि मेरा एन्क्रिप्टेड सामग्री मैन्युअल रूप से बदल दी गई थी तो डिक्रिप्शन फ़ंक्शन कैसे व्यवहार करेगा।

मेरे लिए समाधान एक जगह था

        try
            decryption stuff....
        catch
             inform decryption will not be carried out.
        end try

जैसे मैंने कहा कि मेरी पैडिंग त्रुटि थी क्योंकि मैं नोटपैड का उपयोग करके डिक्रिप्ट किए गए पाठ पर मैन्युअल रूप से टाइप कर रहा था। हो सकता है कि मेरा उत्तर आपके समाधान के लिए आपका मार्गदर्शन करे।


0

मेरी भी यही त्रुटि थी। मेरे मामले में ऐसा इसलिए था क्योंकि मैंने एन्क्रिप्टेड डेटा को SQL डेटाबेस में संग्रहीत किया है। डेटा जिस तालिका में संग्रहीत किया जाता है, उसमें एक बाइनरी (1000) डेटा प्रकार होता है। डेटाबेस से डेटा को पुनः प्राप्त करते समय, यह इन 1000 बाइट्स को डिक्रिप्ट करेगा, जबकि वास्तव में 400 बाइट्स। इसलिए परिणामी शून्य (600) को हटाते हुए इस समस्या को ठीक किया।


0

मेरे पास यह त्रुटि थी और स्पष्ट रूप से रुकावट सेट कर रहा था: aesManaged.BlockSize = 128;

एक बार मैंने उसे हटा दिया, तो यह काम कर गया।


0

मुझे C # के लिए एक गो कार्यक्रम को पोर्ट करने की कोशिश में एक ही समस्या थी। इसका मतलब है कि गो कार्यक्रम के साथ बहुत सारे डेटा पहले से ही एन्क्रिप्ट किए गए हैं। यह डेटा अब C # के साथ डिक्रिप्ट किया जाना चाहिए।

अंतिम समाधान PaddingMode.Noneया बल्कि था PaddingMode.Zeros

गो में क्रिप्टोग्राफिक तरीके:

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/sha1"
    "encoding/base64"
    "io/ioutil"
    "log"

    "golang.org/x/crypto/pbkdf2"
)

func decryptFile(filename string, saltBytes []byte, masterPassword []byte) (artifact string) {

    const (
        keyLength         int = 256
        rfc2898Iterations int = 6
    )

    var (
        encryptedBytesBase64 []byte // The encrypted bytes as base64 chars
        encryptedBytes       []byte // The encrypted bytes
    )

    // Load an encrypted file:
    if bytes, bytesErr := ioutil.ReadFile(filename); bytesErr != nil {
        log.Printf("[%s] There was an error while reading the encrypted file: %s\n", filename, bytesErr.Error())
        return
    } else {
        encryptedBytesBase64 = bytes
    }

    // Decode base64:
    decodedBytes := make([]byte, len(encryptedBytesBase64))
    if countDecoded, decodedErr := base64.StdEncoding.Decode(decodedBytes, encryptedBytesBase64); decodedErr != nil {
        log.Printf("[%s] An error occur while decoding base64 data: %s\n", filename, decodedErr.Error())
        return
    } else {
        encryptedBytes = decodedBytes[:countDecoded]
    }

    // Derive key and vector out of the master password and the salt cf. RFC 2898:
    keyVectorData := pbkdf2.Key(masterPassword, saltBytes, rfc2898Iterations, (keyLength/8)+aes.BlockSize, sha1.New)
    keyBytes := keyVectorData[:keyLength/8]
    vectorBytes := keyVectorData[keyLength/8:]

    // Create an AES cipher:
    if aesBlockDecrypter, aesErr := aes.NewCipher(keyBytes); aesErr != nil {
        log.Printf("[%s] Was not possible to create new AES cipher: %s\n", filename, aesErr.Error())
        return
    } else {

        // CBC mode always works in whole blocks.
        if len(encryptedBytes)%aes.BlockSize != 0 {
            log.Printf("[%s] The encrypted data's length is not a multiple of the block size.\n", filename)
            return
        }

        // Reserve memory for decrypted data. By definition (cf. AES-CBC), it must be the same lenght as the encrypted data:
        decryptedData := make([]byte, len(encryptedBytes))

        // Create the decrypter:
        aesDecrypter := cipher.NewCBCDecrypter(aesBlockDecrypter, vectorBytes)

        // Decrypt the data:
        aesDecrypter.CryptBlocks(decryptedData, encryptedBytes)

        // Cast the decrypted data to string:
        artifact = string(decryptedData)
    }

    return
}

... तथा ...

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/sha1"
    "encoding/base64"
    "github.com/twinj/uuid"
    "golang.org/x/crypto/pbkdf2"
    "io/ioutil"
    "log"
    "math"
    "os"
)

func encryptFile(filename, artifact string, masterPassword []byte) (status bool) {

    const (
        keyLength         int = 256
        rfc2898Iterations int = 6
    )

    status = false
    secretBytesDecrypted := []byte(artifact)

    // Create new salt:
    saltBytes := uuid.NewV4().Bytes()

    // Derive key and vector out of the master password and the salt cf. RFC 2898:
    keyVectorData := pbkdf2.Key(masterPassword, saltBytes, rfc2898Iterations, (keyLength/8)+aes.BlockSize, sha1.New)
    keyBytes := keyVectorData[:keyLength/8]
    vectorBytes := keyVectorData[keyLength/8:]

    // Create an AES cipher:
    if aesBlockEncrypter, aesErr := aes.NewCipher(keyBytes); aesErr != nil {
        log.Printf("[%s] Was not possible to create new AES cipher: %s\n", filename, aesErr.Error())
        return
    } else {

        // CBC mode always works in whole blocks.
        if len(secretBytesDecrypted)%aes.BlockSize != 0 {
            numberNecessaryBlocks := int(math.Ceil(float64(len(secretBytesDecrypted)) / float64(aes.BlockSize)))
            enhanced := make([]byte, numberNecessaryBlocks*aes.BlockSize)
            copy(enhanced, secretBytesDecrypted)
            secretBytesDecrypted = enhanced
        }

        // Reserve memory for encrypted data. By definition (cf. AES-CBC), it must be the same lenght as the plaintext data:
        encryptedData := make([]byte, len(secretBytesDecrypted))

        // Create the encrypter:
        aesEncrypter := cipher.NewCBCEncrypter(aesBlockEncrypter, vectorBytes)

        // Encrypt the data:
        aesEncrypter.CryptBlocks(encryptedData, secretBytesDecrypted)

        // Encode base64:
        encodedBytes := make([]byte, base64.StdEncoding.EncodedLen(len(encryptedData)))
        base64.StdEncoding.Encode(encodedBytes, encryptedData)

        // Allocate memory for the final file's content:
        fileContent := make([]byte, len(saltBytes))
        copy(fileContent, saltBytes)
        fileContent = append(fileContent, 10)
        fileContent = append(fileContent, encodedBytes...)

        // Write the data into a new file. This ensures, that at least the old version is healthy in case that the
        // computer hangs while writing out the file. After a successfully write operation, the old file could be
        // deleted and the new one could be renamed.
        if writeErr := ioutil.WriteFile(filename+"-update.txt", fileContent, 0644); writeErr != nil {
            log.Printf("[%s] Was not able to write out the updated file: %s\n", filename, writeErr.Error())
            return
        } else {
            if renameErr := os.Rename(filename+"-update.txt", filename); renameErr != nil {
                log.Printf("[%s] Was not able to rename the updated file: %s\n", fileContent, renameErr.Error())
            } else {
                status = true
                return
            }
        }

        return
    }
}

अब, C # में डिक्रिप्शन:

public static string FromFile(string filename, byte[] saltBytes, string masterPassword)
{
    var iterations = 6;
    var keyLength = 256;
    var blockSize = 128;
    var result = string.Empty;
    var encryptedBytesBase64 = File.ReadAllBytes(filename);

    // bytes -> string:
    var encryptedBytesBase64String = System.Text.Encoding.UTF8.GetString(encryptedBytesBase64);

    // Decode base64:
    var encryptedBytes = Convert.FromBase64String(encryptedBytesBase64String);
    var keyVectorObj = new Rfc2898DeriveBytes(masterPassword, saltBytes.Length, iterations);
    keyVectorObj.Salt = saltBytes;
    Span<byte> keyVectorData = keyVectorObj.GetBytes(keyLength / 8 + blockSize / 8);
    var key = keyVectorData.Slice(0, keyLength / 8);
    var iv = keyVectorData.Slice(keyLength / 8);

    var aes = Aes.Create();
    aes.Padding = PaddingMode.Zeros;
    // or ... aes.Padding = PaddingMode.None;
    var decryptor = aes.CreateDecryptor(key.ToArray(), iv.ToArray());
    var decryptedString = string.Empty;

    using (var memoryStream = new MemoryStream(encryptedBytes))
    {
        using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
        {
            using (var reader = new StreamReader(cryptoStream))
            {
                decryptedString = reader.ReadToEnd();
            }
        }
    }

    return result;
}

पैडिंग के साथ समस्या को कैसे समझाया जा सकता है? एन्क्रिप्शन से पहले गो कार्यक्रम पेडिंग की जाँच करता है:

// CBC mode always works in whole blocks.
if len(secretBytesDecrypted)%aes.BlockSize != 0 {
    numberNecessaryBlocks := int(math.Ceil(float64(len(secretBytesDecrypted)) / float64(aes.BlockSize)))
    enhanced := make([]byte, numberNecessaryBlocks*aes.BlockSize)
    copy(enhanced, secretBytesDecrypted)
    secretBytesDecrypted = enhanced
}

महत्वपूर्ण हिस्सा यह है:

enhanced := make([]byte, numberNecessaryBlocks*aes.BlockSize)
copy(enhanced, secretBytesDecrypted)

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

इस प्रकार, सी # कोड का उपयोग कर सकते हैं PaddingMode.Zeros। विकल्प PaddingMode.Noneसिर्फ किसी भी पैडिंग को नजरअंदाज करता है, जो काम भी करता है। मुझे उम्मीद है कि यह उत्तर किसी के लिए भी उपयोगी है, जिसे Go से C #, आदि के लिए कोड पोर्ट करना होगा।


0

मुझे क्लाइंट द्वारा वही त्रुटि बताई गई है। मैं व्यक्तिगत रूप से इसे रद्द नहीं कर सकता। एन्क्रिप्ट और डिक्रिप्ट विधियों के कोड को देखते हुए , दोनों के पास PaddingMode.PKCS7 के लिए पैडिंग सेट है । डिक्रिप्ट इस तरह दिखता है और मैं ' फ्लशफाइनलब्लॉक ' के संबंध में समस्या को नहीं देख सकता । क्या कोई इस पर कुछ प्रकाश डाल सकता है?

public string Decrypt(string cipherText)
{
  if (string.IsNullOrEmpty(cipherText))
    return "";
  string result;
  Encoding byteEncoder = Encoding.Default;

  byte[] rijnKey = byteEncoder.GetBytes(Password);
  byte[] rijnIv = byteEncoder.GetBytes(InitialVector);
  RijndaelManaged rijn = new RijndaelManaged { Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 };

  using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText)))
  {
    using (ICryptoTransform decryptor = rijn.CreateDecryptor(rijnKey, rijnIv))
    {
      using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
      {
                    using (StreamReader swDecrypt = new StreamReader(csDecrypt))
                    {
                        result = swDecrypt.ReadToEnd();
                    }
                }
    }
  }
  rijn.Clear();      
  return result.Replace("\0", "");
}

0

मेरी भी यही त्रुटि थी। मेरे मामले में दिए गए पासवर्ड 16 से अधिक है इसका मतलब यह एन्क्रिप्ट किया गया है, लेकिन डिक्रिप्शन के दौरान मुझे यह त्रुटि मिल रही है। एन्क्रिप्शन:

string keyString = "CDFUYP@ssw0rd123";
            var key = Encoding.UTF8.GetBytes(keyString);            
            using (var aesAlg = Aes.Create())
            {
                using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV))
                {
                    using (var msEncrypt = new MemoryStream())
                    {
                        using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                        using (var swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(text);
                        }                          
                        var iv = aesAlg.IV;

                        var decryptedContent = msEncrypt.ToArray();

                        var result = new byte[iv.Length + decryptedContent.Length];

                        Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
                        Buffer.BlockCopy(decryptedContent, 0, result, iv.Length, decryptedContent.Length);

                        var encryptedString = Convert.ToBase64String(result);
                        var decryptedString = Decrypt(encryptedString);
                        if (decryptedString == null)
                        {
                            return null;
                        }
                        return encryptedString;

                    }
                }

डिक्रिप्शन:

 string keyString = "CDFUYP@ssw0rd123";
            var fullCipher = Convert.FromBase64String(cipherText);
            var iv = new byte[16];
            var cipher = new byte[16];
            Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
            Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, iv.Length);
            var key = Encoding.UTF8.GetBytes(keyString);

            using (var aesAlg = Aes.Create())
            {
                using (var decryptor = aesAlg.CreateDecryptor(key, iv))
                {
                    string result;
                    using (var msDecrypt = new MemoryStream(cipher))
                    {
                        using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                        {
                            using (var srDecrypt = new StreamReader(csDecrypt))
                            {
                                result = srDecrypt.ReadToEnd();
                            }
                        }
                    }

                    return result;
                }
            }

हाय @sundarraj, यह एक सवाल है?
टियागो मार्टिंस पेरेस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.