खराब पासवर्ड क्यों होता है "पैडिंग अमान्य है और इसे हटाया नहीं जा सकता"?

मुझे कुछ सरल स्ट्रिंग एन्क्रिप्शन की आवश्यकता थी, इसलिए मैंने निम्नलिखित कोड लिखा ( ):

   //create and initialize a crypto algorithm
    private static SymmetricAlgorithm getAlgorithm(string password) {
        SymmetricAlgorithm algorithm = Rijndael.Create();
        Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(
            password, new byte[] {
            0x53,0x6f,0x64,0x69,0x75,0x6d,0x20,            //salty goodness
            0x43,0x68,0x6c,0x6f,0x72,0x69,0x64,0x65
        }
        );
        algorithm.Padding = PaddingMode.ISO10126;
        algorithm.Key = rdb.GetBytes(32);
        algorithm.IV = rdb.GetBytes(16);
        return algorithm;
    }

    /* 
     * encryptString
     * provides simple encryption of a string, with a given password
     */
    public static string encryptString(string clearText, string password) {
        SymmetricAlgorithm algorithm = getAlgorithm(password);
        byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, algorithm.CreateEncryptor(), CryptoStreamMode.Write);
        cs.Write(clearBytes, 0, clearBytes.Length);
        cs.Close();
        return Convert.ToBase64String(ms.ToArray());
    }

    /*
     * decryptString
     * provides simple decryption of a string, with a given password
     */
    public static string decryptString(string cipherText, string password) {
        SymmetricAlgorithm algorithm = getAlgorithm(password);
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, algorithm.CreateDecryptor(), CryptoStreamMode.Write);
        cs.Write(cipherBytes, 0, cipherBytes.Length);
        cs.Close();            
        return System.Text.Encoding.Unicode.GetString(ms.ToArray());
    }

कोड ठीक काम करता प्रतीत होता है, सिवाय इसके कि जब गलत कुंजी के साथ डेटा डिक्रिप्ट करते हैं, तो मुझे क्रिप्टोग्राफिक एक्सेप्शन मिलता है - "पैडिंग अमान्य है और इसे हटाया नहीं जा सकता" - cs.Close() लाइन पर decryptString में।

उदाहरण कोड:

    string password1 = "password";
    string password2 = "letmein";
    string startClearText = "The quick brown fox jumps over the lazy dog";
    string cipherText = encryptString(startClearText, password1);
    string endClearText = decryptString(cipherText, password2);    //exception thrown

मेरा सवाल है, क्या इसकी उम्मीद की जा सकती है? मैंने सोचा होगा कि गलत पासवर्ड के साथ डिक्रिप्ट करने से अपवाद के बजाय नॉनसेंस आउटपुट होगा।

0
ro fr bn
इसने मुझे आपकी टिप्पणी के साथ इतना समय बचाया: "कोड ठीक काम करने लगता है, सिवाय इसके कि जब गलत कुंजी वाले डेटा को डिक्रिप्ट करते समय" I swore मैंने चाबियाँ कॉपी की थीं, लेकिन 2x देखकर मैंने नहीं किया। उम्मीद है कि यह पैडिंग तंत्र या बदलते कोड को देखने से पहले किसी और की मदद करता है।
जोड़ा लेखक atconway, स्रोत

10 उत्तर

मुझे एक ही समस्या थी, डिक्रिप्ट विधि में समस्या एक खाली मेमोरी स्ट्रीम शुरू कर रही थी। जब यह काम करता था जब मैंने इसे सिफर टेक्स्ट बाइट सरणी के साथ शुरू किया:

MemoryStream ms = new MemoryStream(cipherText)
0
जोड़ा

यद्यपि यह पहले से ही उत्तर दिया गया है, मुझे लगता है कि क्यों की अपेक्षा की जानी चाहिए, यह समझना एक अच्छा विचार होगा।

एक पैडिंग योजना आमतौर पर लागू होती है क्योंकि अधिकांश क्रिप्टोग्राफिक फिल्टर अर्थपूर्ण रूप से सुरक्षित नहीं होते हैं और कुछ प्रकार के क्रिप्टोटाक्स को रोकने के लिए नहीं होते हैं। उदाहरण के लिए, आमतौर पर आरएसए में ओएईपी पैडिंग योजना का उपयोग किया जाता है जो कुछ प्रकार के हमलों को रोकता है (जैसे कि एक चुना गया सादा पाठ हमला या अंधेरा )।

एक पैडिंग योजना संदेश भेजने से पहले संदेश मीटर में कुछ (आमतौर पर) यादृच्छिक कचरा जोड़ती है। ओएईपी विधि में, उदाहरण के लिए, दो ओरेकल का उपयोग किया जाता है (यह एक सरल व्याख्या है):

  1. मॉड्यूलस के आकार को देखते हुए आप 0 और k0 बिट्स को यादृच्छिक संख्या के साथ padd k1 बिट्स देते हैं।
  2. फिर संदेश में कुछ परिवर्तन लागू करके आप गद्देदार संदेश प्राप्त करते हैं जो एन्क्रिप्ट किया जाता है और भेजा जाता है।

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

0
जोड़ा
जॉर्ज, स्पष्टीकरण के लिए धन्यवाद। मैं वर्णित वही व्यवहार देख रहा हूं, जो डेटा डिक्रिप्ट किया गया है वह सही है। क्या मुझे यह अपवाद खाना चाहिए, या (उम्मीद है) कुछ ऐसा है जो मैं गलत तरीके से कर रहा हूं कि मैं सही कर सकता हूं? अपवाद फेंकने पर क्या गलत हो रहा है? मेरे द्वारा पढ़ी गई सभी पोस्ट उन लोगों द्वारा लिखी गई हैं जो अपवाद को दूर करने में अधिक रुचि रखते हैं। मेरे मामले में मैं चाहता हूं कि मेरा उपयोग सही हो :)
जोड़ा लेखक stuck, स्रोत
@zaph मैं सामान्य रूप से समझा रहा हूं कि जब आप उपयोग और अमान्य पासवर्ड का डिक्रिप्ट करते हैं तो आपको कचरे के बजाय अमान्य पैडिंग अपवाद क्यों मिलता है। आरएसए सिर्फ एक उदाहरण था, इस्तेमाल की जाने वाली विशिष्ट पैडिंग योजना और उदाहरण थी। यह ओप प्रश्न का उत्तर देता है क्योंकि यह कहता है: हां, यह उम्मीद की जाती है और यहां और क्यों अजीब "पैडिंग" संदर्भ के बारे में स्पष्टीकरण है कि आप केवल तभी समझ सकते हैं जब आप समझते हैं कि पैडिंग योजना क्या है और इसका उपयोग क्यों किया जाता है, लेकिन आपको अगर आप नहीं करते हैं तो परेशान (पैडिंग के साथ एन्क्रिप्शन को क्या करना है ???)
जोड़ा लेखक Jorge Córdoba, स्रोत
यह ओपी के सवाल का जवाब नहीं देता है, सवाल एक सममित ब्लॉक सिफर रिजेंडेल के बारे में है, आरएसए जैसे असममित सिफर नहीं। एक ब्लॉक सिफर पैडिंग के लिए डेटा को ब्लॉक आकार के एक से अधिक एन्क्रिप्ट करने के लिए जोड़ा जाता है, आमतौर पर पीकेसीएस # 7 (नी पीकेसीएस # 5) का उपयोग करते हुए। इन पैडिंग योजनाओं के साथ यादृच्छिक बाइट्स नहीं जोड़े गए हैं। ध्यान दें कि पैडिंग आईएसओ 10126 वापस ले लिया गया था और यादृच्छिक बाइट्स ने कोई सुरक्षा नहीं जोड़ा था। जवाब बिंदु पर होगा अगर यह सममित एन्क्रिप्शन पैडिंग से बात की। सुझाव: प्रश्न का उत्तर देने के लिए उत्तर को ठीक करें। ज़ोमग, वरिष्ठ डेवलपर।
जोड़ा लेखक zaph, स्रोत
सवाल रिजेंडेल पैडिंग के बारे में है और आप आरएसए पैडिंग की व्याख्या करते हैं जो विभिन्न कारणों से बहुत अलग और किया जाता है। ठीक है, मैं समझता हूं कि लोग सममित और असममित एन्क्रिप्शन के बीच के अंतर के बारे में भ्रमित हो जाते हैं और आरएसए देर से अधिक दिखाई देता है और कई लोग आरएसए का उपयोग कर रहे हैं जब एईएस बेहतर फिट है। लेकिन जवाब बेहतर होगा अगर यह बेहतर होगा।
जोड़ा लेखक zaph, स्रोत

मुझे पैडिंग अमान्य है और इसे हटाया नहीं जा सकता संदेश भी प्राप्त हो रहा था। जैसा कि ऊपर बताया गया है, कारण क्रिप्टोस्ट्रीम में कुछ बफर बाइट्स था। फ्लशफिनलब्लॉक() विधि को कॉल करके यह तय किया गया था:

using (CryptoStream cryptoStream = new CryptoStream(memoryStream, algorithm.CreateDecryptor(), CryptoStreamMode.Write)) {
    cryptoStream.Write(bytes, 0, bytes.Length);
    cryptoStream.FlushFinalBlock();
    result = Encoding.UTF8.GetString(memoryStream.ToArray());
    return result;
}
0
जोड़ा

यदि आपने कुंजी-मिलान से इंकार कर दिया है, तो FlushFinalBlock() के अलावा (Yaniv का उत्तर देखें), CryptoStream पर Close() को कॉल करना भी पर्याप्त है।

यदि आप ब्लॉक का उपयोग करके सख्ती से संसाधनों की सफाई कर रहे हैं, तो सुनिश्चित करें कि CryptoStream के लिए ब्लॉक को घोंसला करना सुनिश्चित करें:

using (MemoryStream ms = new MemoryStream())
using (var enc = RijndaelAlg.CreateEncryptor())
{
  using (CryptoStream encStream = new CryptoStream(ms, enc, CryptoStreamMode.Write))
  {
    encStream.Write(bar2, 0, bar2.Length);
  }//implicit close
  byte[] encArray = ms.ToArray();
}

मुझे इस (या समान) द्वारा काटा गया है:

using (MemoryStream ms = new MemoryStream())
using (var enc = RijndaelAlg.CreateEncryptor())
using (CryptoStream encStream = new CryptoStream(ms, enc, CryptoStreamMode.Write))
{
  encStream.Write(bar2, 0, bar2.Length);
  byte[] encArray = ms.ToArray();
}//implicit close -- too late!
0
जोड़ा
लेकिन अगर आप encStream.FlushFinalBlock() करते हैं तो मुझे लगता है कि इससे कोई फर्क नहीं पड़ता कि आप कहां करते हैं ms.ToArray() (चाहे <�कोड> CryptoStream </कोड> <�कोड> का उपयोग कर)।
जोड़ा लेखक nawfal, स्रोत
ओपी जानता है कि यह एक महत्वपूर्ण विसंगति है जिससे त्रुटि हुई और पूछा कि एक महत्वपूर्ण विसंगति इस त्रुटि का कारण बनती है।
जोड़ा लेखक jbtule, स्रोत

हां, यह उम्मीद की जा रही है, या कम से कम, यह वास्तव में तब होता है जब हमारे क्रिप्टो दिनचर्या गैर-डिक्रिप्ट करने योग्य डेटा प्राप्त करते हैं

0
जोड़ा

CryptoStream में कुछ अपठित बाइट्स हो सकते हैं। धारा को पढ़ने से पहले बंद करना मेरे कार्यक्रम में त्रुटि का कारण बन रहा था।

0
जोड़ा

यदि आप अपना उपयोग सही होना चाहते हैं, तो आपको अपने ciphertext में प्रमाणीकरण जोड़ना चाहिए ताकि आप कर सकें सत्यापित करें कि यह सही पासवर्ड है या सिफरटेक्स्ट को संशोधित नहीं किया गया है। आप जिस पैडिंग का उपयोग कर रहे हैं वह ISO10126 केवल अंतिम अपवाद फेंक देगा बाइट पैडिंग (0x01-0x10) के लिए 16 मान्य मानों में से एक के रूप में डिक्रिप्ट नहीं करता है। तो आपके पास 1/16 का मौका गलत पासवर्ड के साथ अपवाद फेंकने का मौका नहीं है, जहां आप इसे प्रमाणित करते हैं तो आपके पास यह तय करने का एक निश्चित तरीका है कि आपका डिक्रिप्शन मान्य है या नहीं।

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

गलतियों को आसान बनाने के कारण के लिए, मेरे पास एक कोड स्निपेट है, कि मैं समीक्षा और अद्यतित रखने की कोशिश करता हूं (टिप्पणियां, मुद्दों का स्वागत है):

एक स्ट्रिंग सी # के सममित प्रमाणीकृत एन्क्रिप्शन के आधुनिक उदाहरण।

यह आप का उपयोग करते हैं AESThenHMAC.AesSimpleDecryptWithPassword (सिफर, पासवर्ड) जब गलत पासवर्ड प्रयोग किया जाता है, अशक्त लौटा दिया जाता है, अगर सिफर या iv संशोधित किया गया है के बाद एन्क्रिप्शन अशक्त लौटा दिया जाता है, तो आप कभी नहीं कबाड़ डेटा वापस पाने के लिए, या एक गद्दी अपवाद।

0
जोड़ा

मैंने एक समान अनुभव किया "पैडिंग अमान्य है और इसे हटाया नहीं जा सकता है।" अपवाद, लेकिन मेरे मामले में कुंजी चतुर्थ और पैडिंग सही थे।

यह पता चला कि क्रिप्टो धारा को फिसलने से वह सब कुछ गायब था।

इस कदर:

            MemoryStream msr3 = new MemoryStream();
            CryptoStream encStream = new CryptoStream(msr3, RijndaelAlg.CreateEncryptor(), CryptoStreamMode.Write);
            encStream.Write(bar2, 0, bar2.Length);
           //unless we flush the stream we would get "Padding is invalid and cannot be removed." exception when decoding
            encStream.FlushFinalBlock();
            byte[] bar3 = msr3.ToArray();
0
जोड़ा
वही encStream.Close (); करना चाहिए।
जोड़ा लेखक sharpener, स्रोत
यह भी ध्यान रखें कि एक साधारण <�कोड> फ्लश() जिसे आप आमतौर पर स्ट्रीम के साथ करेंगे, नहीं FlushFinalBlock() जैसा कि < कोड> CryptoStream । यह कोड से पहले विवरण में थोड़ा अस्पष्ट है।
जोड़ा लेखक Marc L., स्रोत
यह प्रश्न से असंबंधित है, प्रश्नकर्ता अपवाद का कारण जानता है, खराब पासवर्ड (फ्लशिंग नहीं), और पूछ रहा है कि एक बुरा पासवर्ड इस विशिष्ट अपवाद का कारण बनता है।
जोड़ा लेखक jbtule, स्रोत
हो सकता है कि आपको उन ऑब्जेक्ट्स पर का उपयोग करना चाहिए क्योंकि वे डिस्पोजेबल हैं। वह पर्याप्त होगा।
जोड़ा लेखक user2173353, स्रोत
मुझे एक ही समस्या थी और FlushFinalBlock एक आकर्षण के रूप में काम किया !!!
जोड़ा लेखक Michel Vaz Ramos, स्रोत

उपयोगकर्ता "एटकॉवे" द्वारा अपडेट किया गया जवाब मेरे लिए काम करता है।

समस्या पैडिंग के साथ नहीं थी, लेकिन कुंजी जो एन्क्रिप्शन और डिक्रिप्शन के दौरान अलग थी। कुंजी और iv एक ही मूल्य को समझने और डिक्रिप्ट करने के दौरान समान होना चाहिए।

0
जोड़ा

Another reason of the exception might be a race condition between several threads using decryption logic - native implementations of ICryptoTransform are not thread-safe (e.g. SymmetricAlgorithm), so it should be put to exclusive section, e.g. using lock. Please refer here for more details: http://www.make-awesome.com/2011/07/system-security-cryptography-and-thread-safety/

0
जोड़ा