C ++ में संवेदनशील तारों को अस्पष्ट करने की तकनीक


87

मुझे अपने C ++ एप्लिकेशन में संवेदनशील जानकारी (एक सममित एन्क्रिप्शन कुंजी जिसे मैं निजी रखना चाहता हूं) को संग्रहीत करने की आवश्यकता है। यह करने के लिए सरल तरीका है:

std::string myKey = "mysupersupersecretpasswordthatyouwillneverguess";

हालांकि, stringsप्रक्रिया के माध्यम से एप्लिकेशन को चलाने (या किसी अन्य जो बाइनरी ऐप से तार निकालता है) उपरोक्त स्ट्रिंग को प्रकट करेगा।

ऐसे संवेदनशील डेटा को अस्पष्ट करने के लिए किन तकनीकों का उपयोग किया जाना चाहिए?

संपादित करें:

ठीक है, बहुत सुंदर आप सभी ने कहा है "आपका निष्पादन योग्य रिवर्स इंजीनियर हो सकता है" - बिल्कुल! यह मेरा एक पालतू जानवर है, इसलिए मैं यहाँ थोड़ा रूकने जा रहा हूँ:

ऐसा क्यों है कि 99% (ठीक है, इसलिए शायद मैं इस साइट पर सभी सुरक्षा से संबंधित सवालों का थोड़ा सा अतिशयोक्ति करता हूं) "एक पूरी तरह से सुरक्षित कार्यक्रम बनाने के लिए कोई संभव तरीका नहीं है" की धार के साथ जवाब दिया जाता है - यह एक उपयोगी नहीं है का जवाब! सुरक्षा पूर्ण प्रयोज्य और एक छोर पर कोई सुरक्षा नहीं है, और सही सुरक्षा के बीच एक स्लाइडिंग स्केल है लेकिन दूसरे पर कोई प्रयोज्य नहीं है।

मुद्दा यह है कि आप उस स्लाइडिंग स्केल पर अपना स्थान चुनते हैं, जो इस बात पर निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं और वह वातावरण जिसमें आपका सॉफ़्टवेयर चलेगा। मैं एक सैन्य स्थापना के लिए एक ऐप नहीं लिख रहा हूं, मैं एक होम पीसी के लिए एक ऐप लिख रहा हूं । मुझे पहले से ज्ञात एन्क्रिप्शन कुंजी के साथ एक अविश्वसनीय नेटवर्क में डेटा एन्क्रिप्ट करने की आवश्यकता है। इन मामलों में, "अस्पष्टता के माध्यम से सुरक्षा" संभवतः काफी अच्छी है! निश्चित रूप से, पर्याप्त समय, ऊर्जा और कौशल वाला कोई व्यक्ति द्विआधारी को रिवर्स-इंजीनियर कर सकता है और पासवर्ड खोज सकता है, लेकिन क्या अनुमान लगा सकता है? मुझे परवाह नहीं है:

जिस समय मुझे शीर्ष-पायदान सुरक्षित प्रणाली को लागू करने में समय लगता है, वह फटा संस्करणों के कारण बिक्री के नुकसान की तुलना में अधिक महंगा है (ऐसा नहीं है कि मैं वास्तव में यह बेच रहा हूं, लेकिन आप मेरी बात प्राप्त करें)। यह नीला-आकाश "नए प्रोग्रामर के बीच प्रोग्रामिंग में इसे सबसे अच्छा संभव तरीका देता है" कम से कम कहने के लिए मूर्खतापूर्ण प्रवृत्ति है।

इस प्रश्न का उत्तर देने के लिए समय निकालने के लिए धन्यवाद - वे सबसे अधिक सहायक थे। दुर्भाग्य से मैं केवल एक उत्तर को स्वीकार कर सकता हूं, लेकिन मैंने सभी उपयोगी उत्तरों को वोट दिया है।


2
शायद अगर आप यह वर्णन करते हैं कि आप एन्क्रिप्शन कुंजी को पूरा करने की कोशिश कर रहे हैं, तो हम इस पर सलाह दे सकते हैं कि ऐसा करने की आवश्यकता से कैसे बचें।
जॉशप्री

3
सटीक डुप्लिकेट: stackoverflow.com/questions/926172/…
Kirill V. Lyadvinsky

4
@Kirill: इस प्रश्न को ठीक उसी तरह से कॉल करना मुश्किल है जैसा आप उल्लेख करते हैं। वास्तव में, विचार समान है। सवाल यह नहीं है।
xtofl

1
@xtofl, आप वोट नहीं करने के लिए स्वतंत्र हैं। मेरे लिए यह दो समान प्रश्नों की तरह दिखता है।
किरिल वी। लयाडविंस्की

2
(शेख़ी से असंबंधित) "निजी कुंजी" की परिभाषा एक सार्वजनिक / निजी कुंजी जोड़ी का एक आधा हिस्सा है जिसे आप बाहर नहीं करते हैं। इस मामले में भी, निजी कुंजी वह है जिसे आप अपने सर्वर पर रखते हैं; आपका क्लाइंट ऐप सार्वजनिक है।
MSalters

जवाबों:


42

असल में, अपने कार्यक्रम के लिए उपयोग और एक डिबगर के साथ किसी के कर सकते हैं और करेंगे आवेदन में चाबी मिल वे करना चाहते हैं।

लेकिन, अगर आप केवल यह सुनिश्चित करना चाहते हैं कि कुंजी stringsआपके बाइनरी पर चलने के दौरान दिखाई न दे , तो आप उदाहरण के लिए सुनिश्चित कर सकते हैं कि कुंजी मुद्रण योग्य सीमा के भीतर नहीं है।

XOR के साथ अस्पष्ट कुंजी

उदाहरण के लिए, आप कुंजी को दो बाइट सरणियों में विभाजित करने के लिए XOR का उपयोग कर सकते हैं:

key = key1 XOR key2

यदि आप key1 को उसी बाइट-लंबाई के साथ बनाते हैं जैसा कि keyआप उपयोग कर सकते हैं (पूरी तरह से) यादृच्छिक बाइट मान और फिर गणना करें key2:

key1[n] = crypto_grade_random_number(0..255)
key2[n] = key[n] XOR key1[n]

आप अपने निर्माण के माहौल में ऐसा कर सकते हैं, और उसके बाद ही स्टोर key1और key2अपने आवेदन में।

अपने बाइनरी की रक्षा करना

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

प्रमुख उपकरणों में से एक Themida है , जो आपके बायनेरिज़ की सुरक्षा का एक भयानक काम करता है। इसका उपयोग अक्सर प्रसिद्ध इंजीनियरिंग द्वारा किया जाता है, जैसे Spotify, रिवर्स इंजीनियरिंग से बचाने के लिए। इसमें OllyDbg और Ida Pro जैसे कार्यक्रमों में डिबगिंग को रोकने के लिए सुविधाएँ हैं।

एक बड़ी सूची भी है, शायद कुछ हद तक पुरानी है, आपके बाइनरी की सुरक्षा के लिए
उनमें से कुछ स्वतंत्र हैं।

पासवर्ड मिलान

यहाँ किसी ने हैशिंग पासवर्ड + नमक पर चर्चा की।

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

अंत में, आप उपरोक्त सभी तकनीकों के संयोजन का उपयोग कर सकते हैं।


यदि इसका एक पासवर्ड जिसे उपयोगकर्ता को दर्ज करना है, तो पासवर्ड का हैश + नमक स्टोर करें। नीचे उत्तर देखें।

1
@hapalibashi: आप अपने आवेदन में सुरक्षित रूप से नमक को कैसे स्टोर करते हैं? मुझे नहीं लगता कि ओपी को एक तरह से पासवर्ड मिलान प्रणाली की आवश्यकता थी, स्थैतिक कुंजियों को संग्रहीत करने का एक सामान्य तरीका।
सीएसएल

2
मैंने पाया है कि असंतुष्ट कार्यक्रमों को देखते हुए आमतौर पर बहुत सारे XORs नहीं होते हैं, इसलिए यदि आप कुछ को अस्पष्ट करने के लिए XOR का उपयोग करने की उम्मीद कर रहे हैं, तो ध्यान रखें कि वे खुद पर ध्यान आकर्षित करते हैं।
केबी

2
@kb - यह एक दिलचस्प बिंदु है। मुझे लगता है कि आप बिटकॉइन और ands को xor से बहुत अधिक घटित होते देखेंगे। ए ^ बी == (ए और ~ बी) || (~ a & b)
जेरेमी पॉवेल

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

8

सबसे पहले, महसूस करें कि ऐसा कुछ भी नहीं है जो आप कर सकते हैं जो एक पर्याप्त रूप से निर्धारित हैकर को रोक देगा, और आसपास बहुत सारे हैं। हर खेल और चारों ओर कंसोल पर सुरक्षा अंततः टूट जाती है, इसलिए यह केवल एक अस्थायी सुधार है।

ऐसी 4 चीजें हैं जो आप कर सकते हैं जो आपको कुछ समय तक छिपे रहने की संभावना को बढ़ाएंगी।

1) स्ट्रिंग के तत्वों को किसी तरह से छिपाएं - कुछ स्पष्ट जैसा कि xoring (^ ऑपरेटर) स्ट्रिंग एक और स्ट्रिंग के साथ अच्छा होगा जो स्ट्रिंग को खोजने के लिए असंभव बना देगा।

2) स्ट्रिंग को टुकड़ों में विभाजित करें - अपने स्ट्रिंग और पॉप बिट्स को अजीब मॉड्यूल में अजीब नाम वाले तरीकों में विभाजित करें। इसके माध्यम से खोजना और उसमें स्ट्रिंग के साथ विधि खोजना आसान न करें। बेशक कुछ विधि को इन सभी बिट्स को कॉल करना होगा, लेकिन यह अभी भी इसे थोड़ा कठिन बनाता है।

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

4) एक तदर्थ एल्गोरिथ्म करो - इस सब के ऊपर, एक अद्वितीय मोड़ या दो जोड़ें। हो सकता है कि आप जो कुछ भी पैदा करते हैं उसमें सिर्फ 1 जोड़ें, या दो बार कोई एन्क्रिप्शन करें, या एक चीनी जोड़ें। यह सिर्फ उस हैकर के लिए थोड़ा कठिन होता है जो पहले से ही जानता है कि किसी के उपयोग के समय क्या देखना है, उदाहरण के लिए, वैनिला md5 हैशिंग या RSA एन्क्रिप्शन।

इन सबसे ऊपर, सुनिश्चित करें कि यह बहुत महत्वपूर्ण नहीं है जब (और यह तब होगा जब आप आवेदन काफी लोकप्रिय हो जाते हैं) आपकी कुंजी की खोज हो गई है!


5

पूर्व में उपयोग की गई एक रणनीति है, जो प्रतीत होता है-यादृच्छिक वर्णों की एक सरणी बनाने के लिए है। आप शुरू में सम्मिलित होते हैं, और फिर एक बीजीय प्रक्रिया के साथ अपने विशेष वर्णों का पता लगाते हैं, जहां 0 से N तक के प्रत्येक चरण में एक संख्या <सरणी का आकार होगा, जिसमें आपके अस्पष्ट स्ट्रिंग में अगला वर्ण होता है। (यह जवाब अब अटपटा लग रहा है!)

उदाहरण:

वर्णों की एक सरणी को देखते हुए (संख्या और डैश केवल संदर्भ के लिए हैं)

0123456789
----------
ALFHNFELKD
LKFKFLEHGT
FLKRKLFRFK
FJFJJFJ!JL

और एक समीकरण जिसके पहले छह परिणाम हैं: 3, 6, 7, 10, 21, 47

शब्द "हेलो!" ऊपर के ऐरे से।


अच्छा विचार - मुझे लगता है कि आप सरणी में गैर-मुद्रण वर्णों का उपयोग करके इसे और बेहतर बना सकते हैं ...
Thomi

4

मैं @ चेकर्स से सहमत हूं, आपके निष्पादन योग्य रिवर्स-इंजीनियर हो सकते हैं।

एक बेहतर तरीका यह है कि इसे गतिशील रूप से बनाया जाए, उदाहरण के लिए:

std::string myKey = part1() + part2() + ... + partN();

सच है, कि द्विआधारी खोजते समय स्ट्रिंग का पता चलने से बचा जाता है। हालाँकि, आपकी स्ट्रिंग अभी भी स्मृति में निवासी है .. आपका समाधान संभवतः काफी अच्छा है, हालांकि मैं जो कर रहा हूं उसके लिए।
थोमी

@Thomi, आप, निश्चित रूप से, इसे नष्ट कर सकते हैं जैसे ही आपने इसके साथ किया है। लेकिन फिर भी, यह संवेदनशील तारों को संभालने का सबसे अच्छा तरीका नहीं है ।
निक डंडौलकिस

... नष्ट करने के बाद से यह वास्तव में गारंटी नहीं देता है कि मेमोरी को फिर से सीधे इस्तेमाल किया जाएगा।
Thomi

4

बेशक, सॉफ्टवेयर में निजी डेटा संग्रहीत करना जो उपयोगकर्ता को भेज दिया जाता है वह हमेशा एक जोखिम होता है। कोई भी पर्याप्त रूप से शिक्षित (और समर्पित) इंजीनियर डेटा को उलट सकता है।

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

आपके मामले में, आप गैर-मुद्रण योग्य डेटा के साथ अपने तारों को अव्यवस्थित कर सकते हैं, और फिर इस तरह एक साधारण सहायक फ़ंक्शन का उपयोग करके रनटाइम पर डिकोड कर सकते हैं:

void unscramble( char *s )
{
    for ( char *str = s + 1; *str != 0; str += 2 ) {
        *s++ = *str;
    }
    *s = '\0';
}

void f()
{
    char privateStr[] = "\001H\002e\003l\004l\005o";
    unscramble( privateStr ); // privateStr is 'Hello' now.

    string s = privateStr;
    // ...
}

4

मैंने स्ट्रिंग्स के लिए एक सरल एन्क्रिप्शन टूल बनाया है, यह स्वचालित रूप से एन्क्रिप्ट किए गए स्ट्रिंग्स उत्पन्न कर सकता है और ऐसा करने के लिए कुछ अतिरिक्त विकल्प हैं, कुछ विवरण:

एक वैश्विक चर के रूप में स्ट्रिंग:

// myKey = "mysupersupersecretpasswordthatyouwillneverguess";
unsigned char myKey[48] = { 0xCF, 0x34, 0xF8, 0x5F, 0x5C, 0x3D, 0x22, 0x13, 0xB4, 0xF3, 0x63, 0x7E, 0x6B, 0x34, 0x01, 0xB7, 0xDB, 0x89, 0x9A, 0xB5, 0x1B, 0x22, 0xD4, 0x29, 0xE6, 0x7C, 0x43, 0x0B, 0x27, 0x00, 0x91, 0x5F, 0x14, 0x39, 0xED, 0x74, 0x7D, 0x4B, 0x22, 0x04, 0x48, 0x49, 0xF1, 0x88, 0xBE, 0x29, 0x1F, 0x27 };

myKey[30] -= 0x18;
myKey[39] -= 0x8E;
myKey[3] += 0x16;
myKey[1] += 0x45;
myKey[0] ^= 0xA2;
myKey[24] += 0x8C;
myKey[44] ^= 0xDB;
myKey[15] ^= 0xC5;
myKey[7] += 0x60;
myKey[27] ^= 0x63;
myKey[37] += 0x23;
myKey[2] ^= 0x8B;
myKey[25] ^= 0x18;
myKey[12] ^= 0x18;
myKey[14] ^= 0x62;
myKey[11] ^= 0x0C;
myKey[13] += 0x31;
myKey[6] -= 0xB0;
myKey[22] ^= 0xA3;
myKey[43] += 0xED;
myKey[29] -= 0x8C;
myKey[38] ^= 0x47;
myKey[19] -= 0x54;
myKey[33] -= 0xC2;
myKey[40] += 0x1D;
myKey[20] -= 0xA8;
myKey[34] ^= 0x84;
myKey[8] += 0xC1;
myKey[28] -= 0xC6;
myKey[18] -= 0x2A;
myKey[17] -= 0x15;
myKey[4] ^= 0x2C;
myKey[9] -= 0x83;
myKey[26] += 0x31;
myKey[10] ^= 0x06;
myKey[16] += 0x8A;
myKey[42] += 0x76;
myKey[5] ^= 0x58;
myKey[23] ^= 0x46;
myKey[32] += 0x61;
myKey[41] ^= 0x3B;
myKey[31] ^= 0x30;
myKey[46] ^= 0x6C;
myKey[35] -= 0x08;
myKey[36] ^= 0x11;
myKey[45] -= 0xB6;
myKey[21] += 0x51;
myKey[47] += 0xD9;

डिक्रिप्शन लूप के साथ यूनिकोड स्ट्रिंग के रूप में:

// myKey = "mysupersupersecretpasswordthatyouwillneverguess";
wchar_t myKey[48];

myKey[21] = 0x00A6;
myKey[10] = 0x00B0;
myKey[29] = 0x00A1;
myKey[22] = 0x00A2;
myKey[19] = 0x00B4;
myKey[33] = 0x00A2;
myKey[0] = 0x00B8;
myKey[32] = 0x00A0;
myKey[16] = 0x00B0;
myKey[40] = 0x00B0;
myKey[4] = 0x00A5;
myKey[26] = 0x00A1;
myKey[18] = 0x00A5;
myKey[17] = 0x00A1;
myKey[8] = 0x00A0;
myKey[36] = 0x00B9;
myKey[34] = 0x00BC;
myKey[44] = 0x00B0;
myKey[30] = 0x00AC;
myKey[23] = 0x00BA;
myKey[35] = 0x00B9;
myKey[25] = 0x00B1;
myKey[6] = 0x00A7;
myKey[27] = 0x00BD;
myKey[45] = 0x00A6;
myKey[3] = 0x00A0;
myKey[28] = 0x00B4;
myKey[14] = 0x00B6;
myKey[7] = 0x00A6;
myKey[11] = 0x00A7;
myKey[13] = 0x00B0;
myKey[39] = 0x00A3;
myKey[9] = 0x00A5;
myKey[2] = 0x00A6;
myKey[24] = 0x00A7;
myKey[46] = 0x00A6;
myKey[43] = 0x00A0;
myKey[37] = 0x00BB;
myKey[41] = 0x00A7;
myKey[15] = 0x00A7;
myKey[31] = 0x00BA;
myKey[1] = 0x00AC;
myKey[47] = 0x00D5;
myKey[20] = 0x00A6;
myKey[5] = 0x00B0;
myKey[38] = 0x00B0;
myKey[42] = 0x00B2;
myKey[12] = 0x00A6;

for (unsigned int fngdouk = 0; fngdouk < 48; fngdouk++) myKey[fngdouk] ^= 0x00D5;

एक वैश्विक चर के रूप में स्ट्रिंग:

// myKey = "mysupersupersecretpasswordthatyouwillneverguess";
unsigned char myKey[48] = { 0xAF, 0xBB, 0xB5, 0xB7, 0xB2, 0xA7, 0xB4, 0xB5, 0xB7, 0xB2, 0xA7, 0xB4, 0xB5, 0xA7, 0xA5, 0xB4, 0xA7, 0xB6, 0xB2, 0xA3, 0xB5, 0xB5, 0xB9, 0xB1, 0xB4, 0xA6, 0xB6, 0xAA, 0xA3, 0xB6, 0xBB, 0xB1, 0xB7, 0xB9, 0xAB, 0xAE, 0xAE, 0xB0, 0xA7, 0xB8, 0xA7, 0xB4, 0xA9, 0xB7, 0xA7, 0xB5, 0xB5, 0x42 };

for (unsigned int dzxykdo = 0; dzxykdo < 48; dzxykdo++) myKey[dzxykdo] -= 0x42;

नाह, मैंने काम करने के लिए stringencrypt.com वेबसाइट का उपयोग किया है । इसमें C / C ++ stringencrypt.com/c-cpp-enc एन्क्रिप्शन के लिए उदाहरण हैं जिन्हें आप सरल स्ट्रिंग एन्क्रिप्शन को स्वचालित करने के लिए इसका उपयोग करने पर विचार कर सकते हैं।
बार्टोज़ वोजिक

2

कुछ हद तक निर्भर करता है कि आप जोशरीरी के रूप में क्या करने की कोशिश कर रहे हैं। अनुभव से, मैं कहूंगा कि यदि यह आपके सॉफ़्टवेयर की सुरक्षा के लिए कुछ लाइसेंस योजना का हिस्सा है तो परेशान न करें। वे अंततः इसे रिवर्स इंजीनियर करेंगे। बस साधारण हमलों (इसे पर तार चल लाइन) से बचाने के लिए ROT-13 की तरह एक साधारण सिफर का उपयोग करें। यदि यह उपयोगकर्ताओं को संवेदनशील डेटा को सुरक्षित करने के लिए है, तो मैं सवाल करूंगा कि क्या स्थानीय स्तर पर संग्रहीत निजी कुंजी के साथ उस डेटा की रक्षा करना एक बुद्धिमान कदम है। फिर से यह नीचे आता है कि आप क्या करना चाह रहे हैं।

EDIT: यदि आप इसे करने जा रहे हैं, तो तकनीक का एक संयोजन जो क्रिस को इंगित करता है, रोट 13 से कहीं बेहतर होगा।


2

जैसा कि पहले कहा गया था, आपके स्ट्रिंग को पूरी तरह से सुरक्षित करने का कोई तरीका नहीं है। लेकिन इसे बुद्धिमानी से एक उचित सुरक्षा प्रदान करने के तरीके हैं।

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

बेशक यह हैक किया जा सकता है, लेकिन ऐसा करने के लिए यह एक निर्धारित हैकर लेता है।


अच्छा विचार - अस्पष्टता का एक और रूप एक स्ट्रिंग का उपयोग कर रहा है जो अभी भी काफी मजबूत है (लंबी, विराम चिह्न और वह सब जाज) लेकिन स्पष्ट रूप से पासवर्ड की तरह नहीं दिखता है।
थोमी

1

यदि आप विंडोज़ यूज़र DPAPI, http://msdn.microsoft.com/en-us/library/ms99535.nxx पर हैं

यदि आप मैक पर हैं तो किचेन का उपयोग करें।

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

यह एक सुलझी हुई समस्या है और इसका उत्तर आपके कार्यक्रम के अंदर कुंजी रखना नहीं है :)


1

यह कोशिश करो । स्रोत कोड बताता है कि किसी दिए गए विज़ुअल स्टूडियो c ++ प्रोजेक्ट में सभी स्ट्रिंग्स पर मक्खी को एन्क्रिप्ट और डिक्रिप्ट कैसे किया जाए।


1

एक तरीका जो मैंने हाल ही में आजमाया है:

  1. निजी डेटा का हैश (SHA256) लें और इसे कोड के रूप में पॉप्युलेट करें part1
  2. निजी डेटा और उसके हैश का XOR लें और इसे कोड के रूप में पॉप्युलेट करें part2
  3. डेटा पॉप्युलेट करें: इसे char str [] के रूप में संग्रहीत न करें, लेकिन असाइनमेंट निर्देशों का उपयोग करके रनटाइम पर पॉप्युलेट करें (जैसा कि नीचे मैक्रो में दिखाया गया है)
  4. अब, के XOR लेने के द्वारा रन टाइम पर निजी डेटा उत्पन्न part1औरpart2
  5. अतिरिक्त चरण : उत्पन्न डेटा के हैश की गणना करें और इसके साथ तुलना करें part1। यह निजी डेटा की अखंडता को सत्यापित करेगा।

मैक्रो डेटा को पॉप्युलेट करने के लिए:

मान लीजिए, निजी डेटा 4 बाइट्स का है। हम इसके लिए एक मैक्रो परिभाषित करते हैं जो कुछ यादृच्छिक क्रम में असाइनमेंट निर्देशों के साथ डेटा को बचाता है।

#define POPULATE_DATA(str, i0, i1, i2, i3)\
{\
    char *p = str;\
    p[3] = i3;\
    p[2] = i2;\
    p[0] = i0;\
    p[1] = i1;\
}

अब इस मैक्रो का उपयोग उस कोड में करें जहाँ आपको इसे बचाने की आवश्यकता है part1और part2निम्नानुसार है:

char part1[4] = {0};
char part2[4] = {0};
POPULATE_DATA(part1, 1, 2, 3, 4); 
POPULATE_DATA(part2, 5, 6, 7, 8);

1

एक (बहुत हल्का) हेडर-ओनली प्रोजेक्ट है , जो पूरी तरह से काम करने वाले adamyaxley द्वारा बनाया गया है। यह लैम्बडा फ़ंक्शंस और मैक्रोज़ पर आधारित है और यह कंपाइल-टाइम में एक XOR सिफर के साथ स्ट्रिंग्स को लिबरल एन्क्रिप्ट करता है। यदि आवश्यक हो, तो हम प्रत्येक स्ट्रिंग के लिए बीज को बदल सकते हैं।

निम्न कोड संकलित बाइनरी में स्ट्रिंग "हैलो वर्ल्ड" को संग्रहीत नहीं करेगा।

#include "obfuscate.h"

int main()
{
  std::cout << AY_OBFUSCATE("Hello World") << std::endl;
  return 0;
}

मैंने c ++ 17 और दृश्य स्टूडियो 2019 के साथ परीक्षण किया है, और आईडीए के माध्यम से जांच करता हूं और मैं पुष्टि करता हूं कि स्ट्रिंग छिपी हुई है। ADVobfuscator की तुलना में एक अनमोल लाभ यह है कि यह एक std :: string में परिवर्तनीय है (जबकि संकलित बाइनरी में छिपा हुआ है):

std::string var = AY_OBFUSCATE("string");

0

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


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

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

0

संदर्भ निर्भर लेकिन आप केवल कुंजी के हैश को स्टोर कर सकते हैं और एक नमक (लगातार स्ट्रिंग, अस्पष्ट करना आसान)।

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

नमक शायद इस मामले में अनावश्यक है, यह एक जानवर बल शब्दकोश हमले बंद हो जाता है, तो हैश अलग किया जा सकता (एक गूगल खोज भी काम करने के लिए पता है कि कर दिया गया है)।

एक हैकर को अभी भी केवल पूरे लॉट को बायपास करने के लिए कहीं न कहीं एक जेएमपी इंस्ट्रक्शन डालना होता है, लेकिन यह एक साधारण टेक्स्ट सर्च के बजाय अधिक जटिल है।


यह एक एन्क्रिप्शन कुंजी है, पासवर्ड हैश नहीं। मुझे डेटा को एन्कोड और डिकोड करने के लिए वास्तविक कुंजी की आवश्यकता है। उपयोगकर्ता कभी भी कुंजी नहीं देखता है, यह कभी भी बाइनरी के बाहर संग्रहीत नहीं होता है।
थोमी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.