c# बाइट्स की संख्या को जानने के बिना एक विशेष धारा पढ़ें




ssl stream (2)

इससे पहले कि आप जाकर जॉन स्केट के उत्तर का इस्तेमाल करें, मैं नहीं कर सकता। मैं इस धारा का उपयोग कर रहा हूं जो शुरुआत में महान है, लेकिन अब, मैंने एक छोटी सी समस्या में भाग लिया है मैं अब एक बिंदु पर हूं जहां मुझे उम्मीद है कि डेटा की मात्रा नहीं है, इसलिए मैंने सोचा कि मैं जॉन स्कीट प्रदान की गई विधि का उपयोग करूँगा लेकिन दुर्भाग्य से यह packet = mPackets.Take() पर इंतजार कर रहा है। जब सभी पैकेट पढ़े गए हैं ।

मुझे यह पता नहीं है कि यह कैसे तय किया जाए, स्ट्रीम क्या करता है (शुरुआत में), लेकिन दुर्भाग्य से यह एक ऐसा अवसर है जहां मैं यह नहीं करना चाहता कि इसके लिए क्या किया गया था ...

क्या मुझे readall को फिर से लिखना चाहिए या फिर एक अलग readall पद्धति है जो मेरे मामले में बेहतर काम करेगी?

मैंने 0 लौटने की कोशिश की है, जब कोई भी पैकेट उपलब्ध नहीं था (जब मैं इसे पढ़ना चाहता था और प्रतीक्षा नहीं करता था), लेकिन फिर यह एक IO end of stream exception फेंकता है

मैं वास्तव में एक नुकसान में हूँ, मैं समझता हूं कि मैंने अपने स्वयं के लिए एक गहरे छेद खोला है ...

अब तक मैं पूरी लंबाई से टीएलएस हेडर और जीसीएम IV और एमएसी को घटाकर बेहतर समाधान हासिल नहीं कर पा रहा हूं (जैसा कि नीचे उल्लिखित है) यह 1 सुइट के लिए ठीक काम करता है, लेकिन अब मैं इसका उपयोग नहीं कर रहा हूं भावी साइफर सूट्स के लिए

कुछ संदर्भ इसलिए है कि मैं यह क्यों कर रहा हूं:
मैं एक टीएलएस आधारित एन्क्रिप्शन बनाने के लिए https://github.com/bcgit/bc-csharp का उपयोग कर रहा हूं, हालांकि सीमाओं के कारण मैं उसे टीसीपी स्ट्रीम नहीं सौंप सकता, मैं सभी को टीसीपी परत से एक स्ट्रिंग है, मैं प्रदान नहीं कर सकता यह एक समीप टीसीपी स्ट्रीम के साथ

मैं mockPskTlsServer और ग्राहक का उपयोग कर रहा हूं और मैंने इसे ऐसा बना दिया है:

WaitingStream mStdin = new WaitingStream();
WaitingStream mStdout = new WaitingStream();
CryptoPskTlsClient mServer = new CryptoPskTlsClient(null);
SecureRandom secureRandom = new SecureRandom();
TlsClientProtocol TlsProtocol = new TlsServerProtocol(Stdin, Stdout, secureRandom);
TlsProtocol.Connect(mServer);

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

यह सब ठीक काम करता है, बेहतर किया जा सकता था (कम .... हैक?), लेकिन यह ऐसा करने वाला है।

मैं इसे काम करने के तरीके के बारे में जानता हूं, लेकिन यह एक हैक है और मैं इसे करने के लिए एक शानदार तरीका तलाश रहा हूं। यहां उन में से एक के लिए एक कोड का उदाहरण दिया गया है:

public override string DecryptData(string ciphertext)
{
    byte[] ciphertextBuff = ASCIIEncoding.Default.GetBytes(ciphertext);
    mStdin.Write(ciphertextBuff, 0, ciphertextBuff.Length);

    Stream tlsStream = mServerProtocol.Stream;
    byte[] plaintextBuffer = new byte[ciphertextBuff.Length - 29];//filthy HACK 29 bytes bij AES-GCM want TLS packet = 5, GCM IV = 8, GCM-MAC = 16 totaal = 29.
    Streams.ReadFully(tlsStream, plaintextBuffer);

    string plaintext = ASCIIEncoding.Default.GetString(plaintextBuffer);
    return plaintext;
}

या एक्स आरक्षित बाइट्स में सादा टेक्स्ट लंबाई को टीएलएस पैकेट में डालकर और डिक्रिप्टिंग से पहले इन बाइट्स को पुनः प्राप्त कर सकते हैं।

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

जब मैं ReadAll और ReadFully जैसी विधियों के बारे में बात कर रहा ReadFully मेरा मतलब ये है कि ये विधियां


क्या आपने इसे लिखने के बाद इनपुट स्ट्रीम का निपटान करने की कोशिश की है?

इसे आंतरिक BlockingCollection<byte> mStdIn BlockingCollection<byte> mStdIn BlockingCollection<byte> mStdIn बता देना चाहिए कि कुछ और नहीं आएगा। मुझे यकीन नहीं है कि यह आपके tlsStream को प्रचारित है, यद्यपि।


मैं सभी को टीसीपी परत से एक स्ट्रिंग मिलता है

यह निश्चित रूप से यह काम करने के आपके प्रयासों में घातक दोष है। आप क्या करने की कोशिश कर रहे हैं, यह स्पष्ट है कि टीसीपी कनेक्शन के माध्यम से भेजा गया डेटा TLS एन्क्रिप्ट किया गया है। जो अत्यधिक यादृच्छिक बाइट मान पैदा करता है, 0 और 255 के बीच का कोई भी मान संभव है। डेटा के पार्सल को आप सॉकेट की रीड () कॉल से प्राप्त करते हैं, बाइट [] है, स्ट्रिंग नहीं।

बाइट [] को स्ट्रिंग में कनवर्ट करने के लिए .NET एन्कोडिंग क्लास का उपयोग करना आवश्यक है। इसमें कई किस्में हैं, स्टॉक वाले एएससीआईआईएनकोडिंग, यूनिकोड एन्कोडिंग, यूटीएफ 8 एन्कोडिंग हैं। और एक विशिष्ट कोड पृष्ठ के साथ काम करने के लिए डिज़ाइन कस्टम लोगों का एक गुच्छा, आप उन्हें एन्कोडिंग (इंट कोड पेज) कन्स्ट्रक्टर का उपयोग करके प्राप्त करते हैं।

हमें नहीं पता है कि "टीसीपी परत" द्वारा क्या एन्कोडिंग का उपयोग किया जाता है, जिसे यूटीएफ 8 के साथ काम करने की आवश्यकता है, लेकिन यह एक दिया गया है कि यह हमेशा भ्रष्ट डेटा उत्पन्न करेगा, जब एन्क्रिप्टेड के साथ एक बाइट [] को परिवर्तित करने के लिए कहा जाता है सामग्री। कुछ बाइट मानों के पास एक समान यूनिकोड कोडपॉइंट नहीं है। एन्कोडिंग ऑब्जेक्ट एक तरह से समस्या पैदा करती है जो कि उत्पन्न करती है ? या एक विकल्प चरित्र के रूप में एक । एन्कोडिंग के मूल्य जो भी हो। एन्कोडरफॉलबैक होना चाहिए कुछ बाधाएं जिन्हें आप डिबगर में देख सकते हैं, यद्यपि आवृत्ति अनिश्चित है।

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





bouncycastle