इस उत्तर में, मैं "सिंपल जावा एईएस एनक्रिप्ट / डिक्रिप्ट उदाहरण" मुख्य विषय पर नहीं बल्कि विशिष्ट डिबगिंग प्रश्न का चयन करना चाहता हूं क्योंकि मुझे लगता है कि इससे अधिकांश पाठकों को लाभ होगा।
यह जावा में एईएस एन्क्रिप्शन के बारे में मेरे ब्लॉग पोस्ट का एक सरल सारांश है इसलिए मैं कुछ भी लागू करने से पहले इसके माध्यम से पढ़ने की सलाह देता हूं। लेकिन मैं अभी भी उपयोग करने के लिए एक सरल उदाहरण प्रदान करूंगा और कुछ संकेत दे सकता हूं कि बाहर क्या देखना है।
इस उदाहरण में मैं प्रमाणित एन्क्रिप्शन का उपयोग करना चुनूंगा गैलोज़ / काउंटर मोड या जीसीएम मोड के साथ करना चुनूंगा । कारण यह है कि ज्यादातर मामलों में आप गोपनीयता के साथ अखंडता और प्रामाणिकता चाहते हैं ( ब्लॉग में अधिक पढ़ें )।
एईएस-जीसीएम एन्क्रिप्शन / डिक्रिप्शन ट्यूटोरियल
यहां एईएस-जीसीएम के साथ एन्क्रिप्ट / डिक्रिप्ट करने के लिए आवश्यक कदम हैं जावा क्रिप्टोग्राफी आर्किटेक्चर (जेसीए) के साथ । अन्य उदाहरणों के साथ मिश्रण न करें , क्योंकि सूक्ष्म अंतर आपके कोड को पूरी तरह असुरक्षित बना सकते हैं।
1. कुंजी बनाएँ
जैसा कि यह आपके उपयोग-मामले पर निर्भर करता है, मैं सबसे सरल मामला मानूंगा: एक यादृच्छिक गुप्त कुंजी।
SecureRandom secureRandom = new SecureRandom();
byte[] key = new byte[16];
secureRandom.nextBytes(key);
SecretKey secretKey = SecretKeySpec(key, "AES");
जरूरी:
2. इनिशियलाइज़ेशन वेक्टर बनाएं
एक इनिशियलाइज़ेशन वेक्टर (IV) का उपयोग किया जाता है ताकि एक ही गुप्त कुंजी विभिन्न सिफर ग्रंथों का निर्माण करे ।
byte[] iv = new byte[12]; //NEVER REUSE THIS IV WITH SAME KEY
secureRandom.nextBytes(iv);
जरूरी:
3. IV और कुंजी के साथ एन्क्रिप्ट करें
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv); //128 bit auth tag length
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
byte[] cipherText = cipher.doFinal(plainText);
जरूरी:
- 16 बाइट / 128 बिट प्रमाणीकरण टैग का उपयोग करें (अखंडता / प्रामाणिकता को सत्यापित करने के लिए उपयोग किया जाता है)
- प्रमाणीकरण टैग सिफर पाठ (JCA कार्यान्वयन में) से स्वचालित रूप से जोड़ा जाएगा
- चूंकि GCM एक स्ट्रीम सिफर की तरह व्यवहार करता है, इसलिए किसी प्रकार की पैडिंग की आवश्यकता नहीं है
CipherInputStream
डेटा का बड़ा हिस्सा एन्क्रिप्ट करते समय उपयोग करें
- अतिरिक्त (गैर-गुप्त) डेटा की जाँच करना चाहते हैं यदि इसे बदल दिया गया है? आप यहां अधिक के साथ संबद्ध डेटा का उपयोग करना चाह सकते हैं
cipher.updateAAD(associatedData);
।
3. एकल संदेश के लिए सीरियल
सिर्फ IV और सिफरटेक्स्ट अपीयर करें। जैसा कि ऊपर कहा गया है, IV को गुप्त होने की आवश्यकता नहीं है।
ByteBuffer byteBuffer = ByteBuffer.allocate(iv.length + cipherText.length);
byteBuffer.put(iv);
byteBuffer.put(cipherText);
byte[] cipherMessage = byteBuffer.array();
यदि आपको स्ट्रिंग प्रतिनिधित्व की आवश्यकता है, तो बेस 64 के साथ वैकल्पिक रूप से एनकोड करें । या तो एंड्रॉइड या जावा 8 के अंतर्निहित कार्यान्वयन का उपयोग करें (Apache Commons Codec का उपयोग न करें - यह एक भयानक कार्यान्वयन है)। एन्कोडिंग का उपयोग "कन्वर्ट" बाइट सरणियों को स्ट्रिंग प्रतिनिधित्व करने के लिए किया जाता है ताकि इसे ASCII सुरक्षित बनाया जा सके जैसे:
String base64CipherMessage = Base64.getEncoder().encodeToString(cipherMessage);
4. डिक्रिप्शन तैयार करें: Deserialize
यदि आपने संदेश को इनकोड किया है, तो पहले इसे बाइट सरणी में डिकोड करें:
byte[] cipherMessage = Base64.getDecoder().decode(base64CipherMessage)
जरूरी:
5. डिक्रिप्ट
सिफर को प्रारंभ करें और एन्क्रिप्शन के साथ समान पैरामीटर सेट करें:
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
//use first 12 bytes for iv
AlgorithmParameterSpec gcmIv = new GCMParameterSpec(128, cipherMessage, 0, 12);
cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmIv);
//use everything from 12 bytes on as ciphertext
byte[] plainText = cipher.doFinal(cipherMessage, 12, cipherMessage.length - 12);
जरूरी:
- यदि आपने इसे एन्क्रिप्शन के दौरान जोड़ा है, तो इसके साथ संबद्ध डेटा जोड़ना न भूलें
cipher.updateAAD(associatedData);
।
इस जिस्ट में एक वर्किंग कोड स्निपेट पाया जा सकता है।
ध्यान दें कि सबसे हाल के एंड्रॉइड (एसडीके 21+) और जावा (7+) कार्यान्वयन में एईएस-जीसीएम होना चाहिए। पुराने संस्करणों में इसका अभाव हो सकता है। मैं अभी भी इस मोड को चुनता हूं, क्योंकि यह एनक्रिप्ट-तत्कालीन-मैक (जैसे एईएस-सीबीसी + एचएमएसी के साथ ) के समान मोड की तुलना में अधिक कुशल होने के अलावा लागू करना आसान है । एचईएसी के साथ एईएस-सीबीसी को कैसे लागू किया जाए, इस लेख को देखें ।