2012-09-03 44 views

उत्तर

23

नहीं, आपको SecureRandom(byte[]) कन्स्ट्रक्टर से बचना चाहिए। यह असुरक्षित और गैर पोर्टेबल दोनों है।

यह गैर पोर्टेबल है क्योंकि यह विंडोज बनाम अन्य ऑपरेटिंग सिस्टम पर अलग-अलग व्यवहार करता है।

अधिकांश ओएस पर, डिफ़ॉल्ट एल्गोरिदम "मूल पीआरएनजी" है, जो ओएस (आमतौर पर "/dev/random") से यादृच्छिक डेटा प्राप्त करता है और आपके द्वारा प्रदान किए जाने वाले बीज को अनदेखा करता है।

विंडोज़ पर, डिफ़ॉल्ट एल्गोरिदम "SHA1PRNG" है, जो आपके बीज को काउंटर के साथ जोड़ता है और परिणाम के हैश की गणना करता है।

यह आपके उदाहरण में बुरी खबर है, क्योंकि इनपुट (मिलीसेकंड में वर्तमान यूटीसी समय) में संभावित मूल्यों की अपेक्षाकृत छोटी दूरी है। उदाहरण के लिए यदि कोई हमलावर जानता है कि आरएनजी पिछले 48 घंटों में बीजित किया गया था, तो वे बीज को 2 से कम मूल्यों तक सीमित कर सकते हैं, यानी आपके पास केवल 27 बिट एंट्रॉपी हैं।

यदि दूसरी तरफ आपने विंडोज़ पर डिफ़ॉल्ट SecureRandom() कन्स्ट्रक्टर का उपयोग किया था, तो 128-बिट बीज प्राप्त करने के लिए मूल CryptoGenRandom फ़ंक्शन कहा जाता। तो अपने स्वयं के बीज निर्दिष्ट करके आपने सुरक्षा को कमजोर कर दिया है।

यदि आप वास्तव में डिफ़ॉल्ट बीज (उदाहरण के लिए इकाई परीक्षण के लिए) को ओवरराइड करना चाहते हैं तो आपको एल्गोरिदम भी निर्दिष्ट करना चाहिए। जैसे

SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 
sr.setSeed("abcdefghijklmnop".getBytes("us-ascii")); 

भी देखें How to solve performance problem with Java SecureRandom?
और इस ब्लॉग पोस्ट: http://www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-javas-securerandom/

+1

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

+0

यह वह उत्तर है जिसे मैं उम्मीद कर रहा था, धन्यवाद! –

+0

@ मार्टनबोडवेस आपको क्यों लगता है कि "मूल पीआरएनजी" का उपयोग करते समय बीज को नजरअंदाज कर दिया जाता है? –

1

कोड उचित रूप से सुरक्षित है क्योंकि यह केवल यादृच्छिक बीज को दिए गए बीज का उपयोग नहीं करता है।

इसका उपयोग करने से कहीं अधिक यादृच्छिक नहीं है।

SecureRandom randomizer = new SecureRandom(); 
+2

हाँ, शायद डिफ़ॉल्ट का उपयोग करना बेहतर है - एक मानता है कि एल्गोरिदम के डिजाइनर एक अच्छी बीजिंग योजना चुनेंगे। ऊपर की योजना शायद चरित्र प्रतिनिधित्व में परिवर्तित करके बीज को कमजोर कर देती है। –

+4

डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग करने से यह काफी * कम * यादृच्छिक है। – EJP

+0

@ पीटर Lawrey यहां आप 'new SecureRandom()' का उपयोग करने की सलाह देते हैं लेकिन [this] (http://stackoverflow.com/a/8572501/1317865) पर आप 'System.nanoTime' का उपयोग करने के लिए कहते हैं। [इस] में (http://crypto.stackexchange.com/questions/12306/generate-random-in-secure-message-transfer) स्थिति को मैं 'नया सिक्योररैंडम()' या 'System.nanoTime' का उपयोग करना चाहिए। अग्रिम धन्यवाद – Favolas

2

मुझे लगता है कि यह सबसे अच्छा है SecureRandom बीज ही जाने के लिए। यह सृजन के तुरंत बाद अगली बाइट्स को कॉल करके किया जाता है (कॉलिंग सेट सईड इसे रोक देगा)।

final byte[] dummy = new byte[512]; 
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 
sr.nextBytes(dummy); 

आप क्योंकि यह भी लिनक्स पर एक तेजी से गैर अवरुद्ध कार्यान्वयन, जहां डिफ़ॉल्ट नहीं है की गारंटी देता है SHA1PRNG उपयोग करना चाहते हैं।

+2

यदि 'अगली बाइट्स()' कॉल का उद्देश्य केवल बीजिंग के लात मारने के लिए है, तो मैं 512 बाईज़ का उपयोग नहीं करता बल्कि प्रभावशाली कारणों के लिए केवल 1। – eckes