2014-06-09 5 views
5

मुझे Java क्लाइंट से C# सर्वर पर एन्क्रिप्टेड डेटा भेजने की आवश्यकता है। अभी मैं सीख रहा हूं कि AES (आवश्यकता) का उपयोग कर डेटा एन्क्रिप्ट कैसे करें।बीजिंग से एईएस कुंजी बनाने का बेहतर तरीका SecureRandom

byte[] keyStart = "qweroiwejrwoejlsifeoisrn".getBytes(); // Random character string 

byte[] toEncrypt = myMessageString.getBytes(); 

keyGen = KeyGenerator.getInstance("AES"); 
sr = SecureRandom.getInstance("SHA1PRNG"); 
sr.setSeed(keyStart); 
keyGen.init(128, sr); 
SecretKey secretKey = keyGen.generateKey(); 
byte[] secretKeyByte = secretKey.getEncoded(); 

SecretKeySpec skeySpec = new SecretKeySpec(secretKeyByte, "AES"); 
Cipher cipher = Cipher.getInstance("AES"); 
cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 
cipher.doFinal(toEncrypt); 

एल्गोरिथ्म के बाद से keyStart मुझे यकीन है कि इस SecureRandom बिना, C# में या यहाँ तक कि एक और Java कार्यक्रम में डीकोड किया जा सकता है, तो नहीं कर रहा हूँ का उपयोग कर एक SecureRandom उपयोग करता है: यह स्वीकार कर लिया जवाब android encryption/decryption with AES मैं निम्नलिखित कर रहा हूँ के बाद।

क्या यह एन्क्रिप्शन सिर्फ keyStart की या मैं SecureRandom मैं अभी भी आदेश को डिक्रिप्ट करने में कुछ और पारित करने के लिए की जरूरत का उपयोग कर रहा है क्योंकि मूल्य जानने के साथ/डिक्रिप्शन काम करता है?

इसके अलावा, क्या ऐसा करने का कोई बेहतर तरीका है या यह ठीक है?

उत्तर

15

नहीं है, पूरे विचार है कि आप स्थिर डेटा से कुंजी व्युत्पत्ति के लिए एक SecureRandom का उपयोग करना चाहिए बल्कि खराब है:

  1. SecureRandom के मुख्य समारोह यादृच्छिक मान उत्पन्न करने के लिए है, यह एक जनरेटर के रूप में नहीं किया जाना चाहिए एक प्रमुख धारा के लिए;
  2. SecureRandom, "SHA1PRNG" के साथ तत्काल होने पर एक अच्छी तरह से परिभाषित एल्गोरिदम लागू नहीं होता है, और एल्गोरिदम वास्तव में एक सूर्य जेडीके से दूसरे में बदलने के लिए जाना जाता है;
  3. ओरेकल "SHA1PRNG" के कार्यान्वयन प्रदान की केवल बीज प्रारंभिक बीज का उपयोग करता है, दूसरों को सिर्फ यादृच्छिक पूल करने के लिए बीज जोड़ सकते हैं।

"SHA1PRNG" का उपयोग करके प्रमुख व्युत्पन्न कार्य को एंड्रॉइड के कई संस्करणों पर मुद्दों का उत्पादन करने के लिए जाना जाता है, और किसी अन्य जावा आरई पर असफल हो सकता है।


तो इसके बजाय आपको क्या करना चाहिए?

  1. उपयोग new SecureRandom() या और भी बेहतर, KeyGenerator यादृच्छिक संख्या जनरेटर बोने यदि आप एक नया यादृच्छिक कुंजी की आवश्यकता के बिना वास्तव में एक यादृच्छिक कुंजी उत्पन्न करने,;
  2. सीधे SecretKeySpec को एक ज्ञात कुंजी के byte[] प्रदान करते हैं या हेक्साडेसिमल से डिकोड करने के लिए एक हेक्साडेसिमल डीकोडर का उपयोग करें (ध्यान दें कि यदि कोई दूसरा रास्ता नहीं है कि String उदाहरणों तो ऐसा केवल तभी कर स्मृति से हटाने के लिए कड़ी मेहनत कर रहे हैं);
  3. यदि आप पासवर्ड से कुंजी बनाना चाहते हैं तो PBKDF2 का उपयोग करें (यद्यपि लिंक में प्रदान किए गए एक से अधिक पुनरावृत्ति गणना का उपयोग करें);
  4. यदि आप एक कुंजी बीज से एकाधिक कुंजी बनाना चाहते हैं, तो एक वास्तविक कुंजी आधारित कुंजी व्युत्पन्न तंत्र का उपयोग करें। एचकेडीएफ का उपयोग करें (नीचे देखें)।

विकल्प 4 को प्राथमिकता दी जाएगी यदि बीज द्वारा उत्पन्न किया गया था डिफी-हेलमैन या ईसीडीएच जैसे एक महत्वपूर्ण समझौते एल्गोरिदम।


ध्यान दें कि विकल्प 3 के लिए, PBKDF2, आप ASCII पासवर्ड केवल करने के लिए रखने के लिए बुद्धिमान होगा। यह इस तथ्य के कारण है कि ओरेकल द्वारा पीबीकेडीएफ 2 कार्यान्वयन यूटीएफ -8 एन्कोडिंग का उपयोग नहीं करता है।


विकल्प 4 का सवाल है, मैं Bouncy Castle libraries लिए सब अच्छा KBKDF के जोड़ने के साथ मदद की है तो वहाँ एक KBKDF खुद को लागू करने के लिए यदि आप अपने classpath और/या की सूची में Bouncy कैसल में जोड़ सकते हैं एक की जरूरत नहीं है स्थापित सुरक्षा प्रदाताओं। इस समय शायद सबसे अच्छा KBKDF HKDF है। यदि आप अपने क्लासपाथ में बाउंसी कैसल नहीं जोड़ सकते हैं तो आप व्युत्पन्न डेटा पर "गरीब व्यक्ति" केडीएफ के रूप में SHA-256 आउटपुट के बाएं बाइट्स का उपयोग करना चाहेंगे।

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