क्या मैं सुरक्षित क्रिप्टोग्राफ़िक कुंजियों के लिए std :: array के लिए एक कस्टम एलोकेटर का उपयोग कर सकता हूं?


9

मुझे पता std::arrayहै कि स्टैक में पूरी तरह से आवंटित किया गया है, लेकिन यह प्रश्न सुरक्षा चिंताओं से प्रेरित है, जिसमें दो चीजों की आवश्यकता होती है:

  1. डेटा std::arrayशून्य हो जाएगा या विनाश पर यादृच्छिक हो जाएगा
  2. डेटा को लॉक किया std::arrayजाएगा , जैसे कि यह डिस्क पर न तो क्रैश पर जाता है और न ही स्वैप मेमोरी पर

आमतौर पर, std::vectorसमाधान के लिए एक कस्टम आवंटनकर्ता बनाना है जो इन चीजों को करता है । हालाँकि, के लिए std::array, मैं यह नहीं देखता कि यह कैसे करना है, और इसलिए यह सवाल है।

सबसे अच्छा मैं यह कर सकता है:

template <typename T, std::size_t Size>
struct SecureArray : public std::array<T, Size>
{
    static_assert(std::is_pod<T>::value, "Only POD types allowed")
    static_assert(sizeof(T) == 1, "Only 1-byte types allowed")
    virtual ~SecureArray()
    {
        std::vector<uint8_t> d = RandomBytes(Size); // generates Size random bytes
        std::memcpy(this->data(), d.data(), Size);
    }
}

लेकिन यह स्पष्ट रूप से मेमोरी लॉकिंग का अभाव है और पहली बार std::arrayउपयोग करके प्राप्त की जाने वाली प्रदर्शन योजना को जटिल बनाता std::arrayहै।

क्या कोई बेहतर उपाय है?


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
शमूएल ल्यू

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

@ Maarten-reinstateMonica दुर्भाग्य से कोई भी उत्तर समस्या को साफ तरीके से हल नहीं करता है।
क्वांटम भौतिक विज्ञानी

@ TheQuantumPhysicist इसे एक साफ तरीका माना जाएगा? क्या आप कोशिश कर सकते हैं और उन आवश्यकताओं को स्पष्ट कर सकते हैं? जो एक संभावित समाधान के बारे में भी सोचने में मदद करता है। मुझे लगता है कि मुझे पता हो सकता है कि आपका क्या मतलब है, लेकिन मुझे भी लगता है कि आप शायद अधिक सटीक हो सकते हैं।
मार्टन बोदवेस

@ Maarten-reinstateMonica एक आवंटनकर्ता का उपयोग करना जो हमारे पास पहले से ही किसी तरह से है। खरोंच से सामान को फिर से भरना एक बुरा विचार है और इसे परीक्षण के नरक की आवश्यकता होगी। वह अंतिम उपाय होना चाहिए। नीचे दिए गए उत्तर स्पष्ट समाधानों का सुझाव दे रहे हैं जो मैंने पहले ही उल्लेख किया था कि मैं टिप्पणियों में बच रहा हूं (उन्हें चैट करने से पहले)।
क्वांटम भौतिक विज्ञानी

जवाबों:


5

std::arrayएक आवंटनकर्ता का उपयोग नहीं कर सकता; हालाँकि, ऐसा लगता है कि आपका SecureArray वर्ग एक कस्टम कंस्ट्रक्टर / डिकंस्ट्रक्टर के माध्यम से जो चाहे प्राप्त कर सकता है।

कुछ इस तरह:

#include <sys/mman.h>

template<class T, std::size_t Size>
struct SecureArray : public std::array<T, Size>
{
    // Your static_asserts...

    SecureArray(void) {
        mlock(std::array<T, Size>::data(), sizeof(T) * Size);
    }

    ~SecureArray(void) {
        char *bytes = reinterpret_cast<char *>(std::array<T, Size>::data());
        for (std::size_t i = 0; i < sizeof(T) * Size; i++)
            bytes[i] = 0;
        munlock(bytes, sizeof(T) * N);
    }
};

4

मुझे पता std::arrayहै कि स्टैक में पूरी तरह से आवंटित किया गया है

यह बिल्कुल सच नहीं है। std::arrayकिसी भी मेमोरी को आवंटित नहीं करता है, इसलिए यह निर्भर करता है कि आप इसे कहाँ आवंटित करते हैं।

auto* arr = new std::array<int, 100>(); // BUM! it is allocated on the heap

लेकिन यह स्पष्ट रूप से मेमोरी लॉकिंग का अभाव है और पहली बार std::arrayउपयोग करके प्राप्त की जाने वाली प्रदर्शन योजना को जटिल बनाता std::arrayहै।

सबसे पहले, यह मेमोरी को स्टैक पर लॉक करने की समस्या नहीं है। POSIX उदाहरण देखें:

#include <iostream>
#include <sys/mman.h>
#include <array>

int main()
{
    std::array<int, 3> a = {1, 2, 3};        // std::array allocated on the stack
    if (mlock(a.data(), sizeof(a)) == 0)
    {
        std::cout << "LOCKED" << std::endl;
    }
}

तो, आप बस निर्माता mlockमें या किसी भी पोर्टेबल एनालॉग को कॉल कर सकते हैं SecureArray

दूसरी बात, आप किस प्रदर्शन को पाने की उम्मीद करते हैं? मेमोरी पढ़ने / लिखने की गति इस बात पर निर्भर नहीं करती है कि आप अपने एरे को, ढेर पर या स्टैक पर कहाँ आवंटित करते हैं। तो, यह सब कुछ है कि आप कितनी तेजी से मेमोरी आवंटित और लॉक कर सकते हैं। यदि प्रदर्शन महत्वपूर्ण है, तो मेमोरी लॉकिंग बहुत धीमी हो सकती है (या नहीं, कौन जानता है?) इसे हर बार SecureArrayकंस्ट्रक्टर में कॉल करना है, भले ही मेमोरी स्टैक पर आवंटित की गई हो।

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


यह गति के बारे में बिल्कुल नहीं है, यह सुरक्षा के बारे में है और यह सुनिश्चित करना है कि चीजें स्थानांतरित नहीं की जाती हैं, क्योंकि आमतौर पर इसका मतलब नकल करना है।
मार्टन बॉड्यूस

2
@ Maarten-reinstateMonica हम्म ... ऐसा लगता है कि मैं पहली जगह के std::arrayबजाय का उपयोग करने का इरादा नहीं मिला std::vector। मुझे लगा कि यह आवंटन की गति के बारे में है।
Stas
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.