जावा .class
फ़ाइलों को काफी आसानी से विघटित किया जा सकता है। यदि मुझे कोड में लॉगिन डेटा का उपयोग करना है तो मैं अपने डेटाबेस की सुरक्षा कैसे कर सकता हूं?
जावा .class
फ़ाइलों को काफी आसानी से विघटित किया जा सकता है। यदि मुझे कोड में लॉगिन डेटा का उपयोग करना है तो मैं अपने डेटाबेस की सुरक्षा कैसे कर सकता हूं?
जवाबों:
अपने कोड में कभी भी हार्ड-कोड पासवर्ड न रखें। यह हाल ही में शीर्ष 25 सबसे खतरनाक प्रोग्रामिंग गलतियों में लाया गया था :
अपने सॉफ्टवेयर में एक गुप्त खाते और पासवर्ड को हार्ड-कोड करना बेहद सुविधाजनक है - कुशल रिवर्स इंजीनियरों के लिए। यदि आपके सभी सॉफ़्टवेयर में पासवर्ड समान है, तो अनिवार्य रूप से उस पासवर्ड के ज्ञात होने पर प्रत्येक ग्राहक असुरक्षित हो जाता है। और क्योंकि यह हार्ड-कोडेड है, इसे ठीक करने के लिए बहुत बड़ा दर्द है।
आपको पासवर्ड सहित कॉन्फ़िगरेशन जानकारी को एक अलग फ़ाइल में संग्रहीत करना चाहिए जिसे एप्लिकेशन शुरू होने पर पढ़ता है। यह कूटबन्धन के परिणामस्वरूप पासवर्ड को लीक होने से रोकने का एकमात्र वास्तविक तरीका है (इसे शुरू करने के लिए बाइनरी में कभी संकलित न करें)।
इस सामान्य गलती के बारे में अधिक जानकारी के लिए, आप CWE-259 लेख पढ़ सकते हैं । लेख में समस्या के बारे में अधिक गहन परिभाषा, उदाहरण और बहुत सारी अन्य जानकारी शामिल है।
जावा में, ऐसा करने का सबसे आसान तरीका प्राथमिकता वर्ग का उपयोग करना है। यह सभी प्रकार की प्रोग्राम सेटिंग्स को स्टोर करने के लिए डिज़ाइन किया गया है, जिनमें से कुछ में उपयोगकर्ता नाम और पासवर्ड शामिल हो सकते हैं।
import java.util.prefs.Preferences;
public class DemoApplication {
Preferences preferences =
Preferences.userNodeForPackage(DemoApplication.class);
public void setCredentials(String username, String password) {
preferences.put("db_username", username);
preferences.put("db_password", password);
}
public String getUsername() {
return preferences.get("db_username", null);
}
public String getPassword() {
return preferences.get("db_password", null);
}
// your code here
}
उपरोक्त कोड में, आप कॉल कर सकते हैं setCredentials
उपयोगकर्ता नाम और पासवर्ड के लिए एक डायलॉग संकेत दिखाने के बाद विधि हैं। जब आपको डेटाबेस से कनेक्ट करने की आवश्यकता होती है, तो आप बस getUsername
और का उपयोग कर सकते हैंgetPassword
संग्रहीत मूल्यों को पुनः प्राप्त करने के लिए विधियों का हैं। लॉगिन क्रेडेंशियल आपके बायनेरिज़ में हार्ड-कोडेड नहीं होंगे, इसलिए अपघटन एक सुरक्षा जोखिम पैदा नहीं करेगा।
महत्वपूर्ण लेख: वरीयता फाइलें सिर्फ सादे पाठ XML फाइलें हैं। सुनिश्चित करें कि आप अनधिकृत उपयोगकर्ताओं को कच्ची फ़ाइलों (UNIX अनुमतियाँ, Windows अनुमतियाँ, वगैरह) को देखने से रोकने के लिए उचित कदम उठाएँ। लिनक्स में, कम से कम, यह कोई समस्या नहीं है, क्योंकि कॉल Preferences.userNodeForPackage
करने से वर्तमान उपयोगकर्ता के होम डायरेक्टरी में XML फ़ाइल बन जाएगी, जो अन्य उपयोगकर्ताओं द्वारा वैसे भी गैर-पठनीय है। विंडोज में, स्थिति अलग हो सकती है।
अधिक महत्वपूर्ण नोट्स: इस स्थिति के लिए सही वास्तुकला क्या है, इस जवाब और अन्य की टिप्पणियों में बहुत चर्चा हुई है। मूल प्रश्न वास्तव में उस संदर्भ का उल्लेख नहीं करता है जिसमें आवेदन का उपयोग किया जा रहा है, इसलिए मैं उन दो स्थितियों के बारे में बात करूंगा जिनके बारे में मैं सोच सकता हूं। पहला ऐसा मामला है जिसमें प्रोग्राम का उपयोग करने वाला व्यक्ति पहले से ही जानता है (और जानने के लिए अधिकृत है) डेटाबेस क्रेडेंशियल। दूसरा मामला है जिसमें आप, डेवलपर, प्रोग्राम का उपयोग करने वाले व्यक्ति से डेटाबेस क्रेडेंशियल्स को गुप्त रखने की कोशिश कर रहे हैं।
पहला मामला: उपयोगकर्ता डेटाबेस लॉगिन क्रेडेंशियल जानने के लिए अधिकृत है
इस मामले में, ऊपर वर्णित समाधान मैं काम करेगा। जावाPreference
वर्ग सादा पाठ में उपयोगकर्ता नाम और पासवर्ड संग्रहीत करेगा, लेकिन वरीयता फ़ाइल केवल अधिकृत उपयोगकर्ता द्वारा पठनीय होगी। उपयोगकर्ता केवल एक्सएमएल फ़ाइल को प्राथमिकताएं खोल सकता है और लॉगिन क्रेडेंशियल पढ़ सकता है, लेकिन यह सुरक्षा जोखिम नहीं है क्योंकि उपयोगकर्ता को क्रेडेंशियल्स को शुरू करने के लिए पता था।
दूसरा मामला: उपयोगकर्ता से लॉगिन क्रेडेंशियल छिपाने की कोशिश कर रहा है
यह अधिक जटिल मामला है: उपयोगकर्ता को लॉगिन क्रेडेंशियल का पता नहीं होना चाहिए लेकिन फिर भी डेटाबेस तक पहुंच की आवश्यकता है। इस मामले में, एप्लिकेशन चलाने वाले उपयोगकर्ता के पास डेटाबेस तक सीधी पहुंच होती है, जिसका अर्थ है कि कार्यक्रम को समय से पहले लॉगिन क्रेडेंशियल्स को जानना होगा। ऊपर वर्णित समाधान इस मामले के लिए उपयुक्त नहीं है। आप डेटाबेस लॉगिन क्रेडेंशियल्स को प्राथमिकता फ़ाइल में संग्रहीत कर सकते हैं, लेकिन वह उपयोगकर्ता उस फ़ाइल को पढ़ सकेगा, क्योंकि वे मालिक होंगे। वास्तव में, इस मामले को सुरक्षित तरीके से उपयोग करने का कोई अच्छा तरीका नहीं है।
सही मामला: एक बहु स्तरीय वास्तुकला का उपयोग करना
इसका सही तरीका यह है कि आपके डेटाबेस सर्वर और आपके क्लाइंट एप्लिकेशन के बीच में एक मध्य परत हो, जो व्यक्तिगत उपयोगकर्ताओं को प्रमाणित करता है और सीमित सेट के संचालन की अनुमति देता है। प्रत्येक उपयोगकर्ता के पास स्वयं के लॉगिन क्रेडेंशियल होंगे, लेकिन डेटाबेस सर्वर के लिए नहीं। क्रेडेंशियल्स मध्य परत (व्यावसायिक तर्क स्तरीय) तक पहुंच की अनुमति देगा और प्रत्येक उपयोगकर्ता के लिए अलग होगा।
प्रत्येक उपयोगकर्ता के पास अपना उपयोगकर्ता नाम और पासवर्ड होगा, जिसे किसी भी सुरक्षा जोखिम के बिना प्राथमिकता वाली फ़ाइल में स्थानीय रूप से संग्रहीत किया जा सकता है। इसे थ्री-टियर आर्किटेक्चर (टियर्स आपके डेटाबेस सर्वर, बिजनेस लॉजिक सर्वर और क्लाइंट एप्लिकेशन) कहा जाता है। यह अधिक जटिल है, लेकिन यह वास्तव में इस तरह का काम करने का सबसे सुरक्षित तरीका है।
संचालन का मूल क्रम है:
getInventoryList
।ध्यान दें कि पूरी प्रक्रिया में, क्लाइंट एप्लिकेशन कभी भी डेटाबेस से सीधे नहीं जुड़ता है । व्यापार तर्क स्तर एक प्रमाणित उपयोगकर्ता से एक अनुरोध प्राप्त करता है, एक सूची सूची के लिए ग्राहक के अनुरोध को संसाधित करता है, और उसके बाद ही एक SQL क्वेरी निष्पादित करता है।
पासवर्ड को एक फाइल में डालें जिसे एप्लिकेशन पढ़ेगा। स्रोत फ़ाइल में पासवर्ड एम्बेड न करें। अवधि।
रूबी के पास इस तरह के उपयोग के लिए DBI :: DBRC नामक एक अल्पज्ञात मॉड्यूल है । मुझे कोई संदेह नहीं है कि जावा में एक समकक्ष है। वैसे भी, एक लिखना मुश्किल नहीं है।
क्या आप एक वेब एप्लिकेशन लिख रहे हैं? यदि हां, तो JNDI का उपयोग इसे बाहरी रूप से एप्लिकेशन में कॉन्फ़िगर करने के लिए करें। एक अवलोकन यहाँ उपलब्ध है :
JNDI नेटवर्क पर दूरस्थ सेवाओं को खोजने और उन तक पहुंचने के लिए एक एप्लिकेशन के लिए एक समान तरीका प्रदान करता है। रिमोट सेवा किसी भी उद्यम सेवा हो सकती है, जिसमें एक संदेश सेवा या एक एप्लिकेशन-विशिष्ट सेवा शामिल है, लेकिन, निश्चित रूप से, एक जेडीबीसी एप्लिकेशन मुख्य रूप से डेटाबेस सेवा में रुचि रखता है। एक बार जब एक DataSource ऑब्जेक्ट JNDI नामकरण सेवा के साथ बनाया और पंजीकृत किया जाता है, तो एक एप्लिकेशन JNDI API का उपयोग उस DataSource ऑब्जेक्ट को एक्सेस करने के लिए कर सकता है, जो तब उस डेटा स्रोत से जुड़ने के लिए उपयोग किया जा सकता है जो इसका प्रतिनिधित्व करता है।
कोई फर्क नहीं पड़ता कि आप क्या करते हैं, संवेदनशील जानकारी कहीं न कहीं किसी फ़ाइल में संग्रहीत की जाएगी। आपका लक्ष्य जितना संभव हो उतना कठिन बनाना है। आप इसे कितना प्राप्त कर सकते हैं यह आपकी परियोजना, जरूरतों और आपकी कंपनी के बटुए की मोटाई पर निर्भर करता है।
सबसे अच्छा तरीका है कि किसी भी पासवर्ड को कहीं भी स्टोर न करें। पासवर्ड हैश को जेनरेट और स्टोर करने के लिए हैश फ़ंक्शन का उपयोग करके इसे प्राप्त किया जाता है:
hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hbllo") = 58756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238f3364946366
हैश एल्गोरिदम एक तरह से कार्य हैं। वे किसी भी डेटा को एक निश्चित-लंबाई "फिंगरप्रिंट" में बदल देते हैं जिसे उलटा नहीं किया जा सकता है। उनके पास यह संपत्ति भी है कि यदि इनपुट थोड़ा सा भी बदलता है, तो परिणामस्वरूप हैश पूरी तरह से अलग है (ऊपर उदाहरण देखें)। यह पासवर्ड की सुरक्षा के लिए बहुत अच्छा है, क्योंकि हम पासवर्ड को ऐसे रूप में संग्रहीत करना चाहते हैं जो उनकी रक्षा करता है भले ही पासवर्ड फ़ाइल स्वयं समझौता हो, लेकिन साथ ही, हमें यह सत्यापित करने में सक्षम होना चाहिए कि उपयोगकर्ता का पासवर्ड सही है।
असंबंधित नोट: इंटरनेट के पुराने दिनों में, जब आप 'मेरे पासवर्ड भूल गए' लिंक पर क्लिक करते हैं, तो वेबसाइटें आपको अपना सादा पाठ पासवर्ड ईमेल करती हैं। वे शायद उन लोगों को डेटाबेस में संग्रहीत कर रहे थे। जब हैकर्स ने अपने डेटाबेस तक पहुंच प्राप्त की, तो वे सभी पासवर्ड तक पहुंच प्राप्त करेंगे। चूंकि कई उपयोगकर्ता कई वेबसाइटों में एक ही पासवर्ड का उपयोग करेंगे, यह एक बड़ी सुरक्षा समस्या थी। सौभाग्य से, आजकल यह आम बात नहीं है।
अब सवाल आता है: पासवर्ड स्टोर करने का सबसे अच्छा तरीका क्या है? मैं इस पर विचार करूंगा (प्रमाणीकरण और उपयोगकर्ता प्रबंधन सेवा तूफानी का समाधान ) एक बहुत लानत आदर्श एक:
जाहिर है कि आप Google या बैंक नहीं हैं, इसलिए यह आपके लिए एक ओवरकिल समाधान है। लेकिन फिर सवाल आता है: आपके प्रोजेक्ट को कितनी सुरक्षा चाहिए, आपके पास कितना समय और पैसा है?
कई अनुप्रयोगों के लिए, हालांकि अनुशंसित नहीं है, कोड में हार्ड-कोडित पासवर्ड संग्रहीत करना एक अच्छा पर्याप्त समाधान हो सकता है। हालांकि, उपरोक्त सूची से सुरक्षा के अतिरिक्त चरणों के जोड़े को आसानी से जोड़कर, आप अपने आवेदन को अधिक सुरक्षित बना सकते हैं।
उदाहरण के लिए, मान लें कि चरण 1 आपकी परियोजना के लिए स्वीकार्य समाधान नहीं है। आप चाहते हैं कि उपयोगकर्ता हर बार पासवर्ड न डालें, या आप उपयोगकर्ताओं को पासवर्ड जानने की आवश्यकता भी नहीं चाहते हैं। फिर भी आपके पास कहीं संवेदनशील जानकारी है और आप इसकी रक्षा करना चाहते हैं। आपके पास एक सरल एप्लिकेशन है, आपकी फ़ाइलों को संग्रहीत करने के लिए कोई सर्वर नहीं है या यह आपकी परियोजना के लिए बहुत अधिक परेशानी है। आपका एप्लिकेशन उन वातावरणों पर चलता है, जहाँ फ़ाइलों को सुरक्षित रूप से संग्रहीत करना संभव नहीं है। यह सबसे खराब स्थिति में से एक है, लेकिन फिर भी कुछ अतिरिक्त सुरक्षा उपाय के साथ आपके पास ज्यादा सुरक्षित समाधान हो सकता है। उदाहरण के लिए, आप किसी फ़ाइल में संवेदनशील जानकारी संग्रहीत कर सकते हैं, और आप फ़ाइल को एन्क्रिप्ट कर सकते हैं। आप कोड में एन्क्रिप्शन निजी कुंजी हार्ड कोडित कर सकते हैं। आप कोड को बाधित कर सकते हैं, इसलिए आप इसे किसी को क्रैक करना थोड़ा मुश्किल बना देते हैं।यह लिंक । (मैं आपको एक बार और चेतावनी देना चाहता हूं कि यह 100% सुरक्षित नहीं है। सही ज्ञान और उपकरणों के साथ एक स्मार्ट हैकर इसे हैक कर सकता है। लेकिन आपकी आवश्यकताओं और आवश्यकताओं के आधार पर, यह आपके लिए एक अच्छा पर्याप्त समाधान हो सकता है)।
यह प्रश्न दिखाता है कि एन्क्रिप्टेड फ़ाइल में पासवर्ड और अन्य डेटा को कैसे संग्रहीत किया जाए: जावा 256-बिट एईएस पासवर्ड-आधारित एन्क्रिप्शन
MD5 एक हैश एल्गोरिथ्म है, एक एन्क्रिप्शन एल्गोरिथ्म नहीं, शॉर्ट यू कैंट में वाट्स यू हैशेड मिलता है, यू केवल तुलना कर सकते हैं। उपयोगकर्ता प्रमाणीकरण जानकारी संग्रहीत करते समय आदर्श रूप से इसका उपयोग किया जाना चाहिए और उपयोगकर्ता नाम और पासवर्ड डीबी नहीं। db उपयोगकर्ता नाम और pwd को एन्क्रिप्ट किया जाना चाहिए और कम से कम करने के लिए एक कॉन्फ़िगर फ़ाइल में रखा जाना चाहिए।