2015-06-11 3 views
7

वाइप हो रहा है मैं एक MemoryStream से एक unencrypted कुंजी को पुन: प्राप्त कर रहा हूँ, यह स्ट्रिंग के कुछ प्रकार में परिवर्तित करने, और नेट के crypto कार्यों के साथ कि स्ट्रिंग का उपयोग डेटा एन्क्रिप्ट करने के। मुझे यह सुनिश्चित करने की ज़रूरत है कि unencrypted कुंजी इसका उपयोग करने के बाद स्मृति से मिटा दी गई है। मुझे SecureString मिला, जो मुझे लगता है कि स्ट्रिंग का ख्याल रखेगा, लेकिन मुझे यकीन नहीं है कि SecureString बनने से पहले कुंजी की स्मृति को कैसे मिटाया जाए।MemoryStream: स्मृति

तो जिस तरह से सब कुछ काम करता है:

MemoryStream -> चार [] -> SecureString

SecureString, चार सरणी के लिए सूचक पारित हो जाता है तो यह चार सरणी जब यह मिट समाप्त हो गया है? यह कन्स्ट्रक्टर है:

SecureString(Char*,int32) 

here लागू करने वाला एक उदाहरण है।

हालांकि, एक बार SecureString डेटा मिटा (अगर यह डेटा मिटा), मैं अभी भी पता करने के लिए MemoryStream में डाटा मिटा करने के लिए कैसे की जरूरत है, और किसी भी मध्यवर्ती वस्तुओं मैं आदेश char[] प्राप्त करने के लिए बनाने के लिए है। स्मृति में कुछ और उत्पादन के बिना

कैसे एक सीधे एक char[] में एक MemoryStream पढ़ा करता है:

तो इस सवाल का दो भागों करने पर निर्भर करता? (और अगर यह संभव नहीं है, क्या आदर्श संक्रमण, MemoryStream -> string -> char[] है? यानी?)

और,

कैसे एक स्मृति MemoryStream द्वारा प्रयोग किया जाता है (और MemStream->char[] प्रक्रिया में बनाए गए किसी अन्य हस्ताक्षर के ऊपर लिख करता) जब समाप्त हो जाए?

+1

क्या आप _without memory_ में कुछ और निर्माण करके क्या मतलब है? जब आप अपनी स्ट्रीम पढ़ते हैं, तो आपकी कुंजी स्मृति में _already_ है - संभवतः अनएन्क्रिप्टेड। आप इसे स्थानीय 'char []' में पढ़ सकते हैं और 'सिक्योरस्ट्रिंग' पर जा सकते हैं। एक बार पूरा होने के बाद सरणी को ओवरराइट और हटाएं। क्या यह वह नहीं है जिसे आप ढूंढ रहे हैं? – xxbbcc

+0

[इसके लिए खाते में संपादित प्रश्न] हाँ, मैं भी यही सोच रहा था। मैं मैन्युअल रूप से स्मृति में कुछ भी ओवरराइट करने से बचने की कोशिश कर रहा था (क्योंकि मुझे नहीं पता कि यह कैसे करना है)। तो अगर मेरे पास मेमोरी स्ट्रीम है, तो इसे char [] में पढ़ें, सुरक्षित स्ट्रिंग का उपयोग करें (जो चार सरणी को सही करता है, है ना?) तो मुझे मेमोरीस्ट्रीम से मेमोरी मिटा देना होगा ... सही? मुझे यह कैसे करना है? क्या कुछ और बनाया गया है? – bordeo

+0

संक्षिप्त उत्तर आप नहीं कर सकते हैं। जैसे ही आपको नियमित रूप से प्रबंधित स्ट्रिंग में डेटा मिल गया है, आप पहले ही खो चुके हैं, और इससे छुटकारा पाने के लिए कोई वास्तविक विश्वसनीय तरीका नहीं है। – Servy

उत्तर

1

सबसे पहले, SecureString इनपुट char* इनपुट की स्मृति को मिटा नहीं देता है - आप इसके लिए ज़िम्मेदार हैं। यह केवल अपने आंतरिक भंडारण को साफ करेगा।

(यह सोचते हैं कि अपनी स्ट्रीम एक मान्य स्ट्रिंग)/साफ MemoryStream की सामग्री को एक स्थानीय char[] में, आप बस सरणी आवंटित कर सकते हैं पढ़ने के लिए:

// Get the contents of the stream. 
var byKey = oMS.GetBuffer(); 

fixed (byte *pBytes = byKey) 
{ 
    var oSecStr = new SecureString ((char*) pBytes, 
     (int) (oMS.Length/2)); 

    // Clear stream (there's no separate char/byte array 
    // to clean). 
    Array.Clear (byKey, 0, byKey.Length); 
} 

यह सब, ज़ाहिर है, मान लिया गया unsafe कोड। हालांकि, स्मृति से कुंजी के सभी संभावित उदाहरणों को साफ़ करने के लिए पूरी तरह से गारंटीकृत तरीका नहीं है - कॉल में कुंजी प्राप्त करने के लिए कॉल के दौरान, इसे कई बार कॉपी किया जा सकता है (विभिन्न निजी बफर में जिनके पास आपकी पहुंच नहीं है) आप शायद चारों ओर घूमने वाली प्रतियों की संख्या भी नहीं जान पाएंगे।

+0

हालांकि आपको ToArray के बजाय मेमोरीस्टेम्स GetBuffer का उपयोग करना चाहिए। यह मेमोरीस्ट्रीम – CSharpie

+0

@CSharpie True के आंतरिक बफर की प्रतिलिपि बनाने से बचाता है। मैं नमूना अद्यतन करूंगा। – xxbbcc

+0

ToArray एक अतिरिक्त प्रतिलिपि बनायेगा, GetBuffer नहीं करेगा। इसके अलावा, यदि आप लंबाई भी नहीं है तो आप अंतिम बाइट को छोटा कर रहे हैं। – Zotta

1

आप जो भी कोशिश कर रहे हैं उससे कहीं अधिक समस्याग्रस्त है। एक मेमोरीस्ट्रीम का सबसे अधिक इस्तेमाल किसी अन्य चीज द्वारा किया जाता है और अधिकतर समय के साथ आकार में बढ़ता है।

हर बार जब वह बढ़ता है, डेटा एक नई सरणी में आंतरिक रूप से कॉपी किया जाता है और पुराने एक मुक्त हो जाता है => अपने प्रमुख यहाँ

इसके अलावा रिसाव सकता है, एक MemoryStream सबसे अधिक संभावना कुछ अन्य एपीआई द्वारा किया जाता है। अन्य एपीआई अधिकतर कुंजी को सुरक्षित रूप से हटा नहीं पाएंगे, क्योंकि उन्हें ऐसा करने के लिए डिज़ाइन नहीं किया गया है।

लेकिन अपने मूल सवाल का जवाब देने: कुंजी सिर्फ ASCII वर्ण है, तो आप सिर्फ एक चार सरणी में बाइट्स कॉपी और यादृच्छिक कबाड़ के साथ मूल बाइट्स के ऊपर लिख सकते हैं। आप सीधे GetBuffer का उपयोग कर अपनी सामग्री को acces कर सकते हैं।

+0

मुझे शायद अपने मालिक के साथ इन उत्तरों की समीक्षा करनी है ... – bordeo

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