java जावा एईएस/जीसीएम/नोपैडिंग-cipher.getIV() मुझे क्या दे रहा है?



security encryption (1)

प्रश्न 1: क्या IV IV cipher.getIV () द्वारा मेरे लिए इस तरह उपयोग करने के लिए सुरक्षित है?

हां, कम से कम ओरेकल के कार्यान्वयन के लिए यह कम से कम है। यह डिफ़ॉल्ट SecureRandom कार्यान्वयन का उपयोग कर अलग से उत्पन्न होता है। चूंकि यह आकार में 12 बाइट्स (जीसीएम के लिए डिफ़ॉल्ट) है, तो आपके पास यादृच्छिकता के 96 बिट हैं। काउंटर दोहराने का मौका बहुत कम है। आप ओपनजेडीके (जीपीएलएड) में स्रोत देख सकते हैं जो ओरेकल जेडीके पर आधारित है।

हालांकि मैं आपको अभी भी अपने 12 यादृच्छिक बाइट्स उत्पन्न करने की सलाह दूंगा क्योंकि अन्य प्रदाता अलग-अलग व्यवहार कर सकते हैं।

प्रश्न 2: क्या वह चतुर्थ हमेशा 12 बाइट लंबा है?

यह बेहद संभव है क्योंकि यह जीसीएम डिफ़ॉल्ट है, लेकिन अन्य लंबाई जीसीएम के लिए मान्य हैं । हालांकि एल्गोरिदम को 12 बाइट्स से किसी भी अन्य आकार के लिए अतिरिक्त गणना करना होगा। कमजोरियों के कारण इसे 12 बाइट / 96 बिट्स पर रखने की दृढ़ता से अनुशंसा की जाती है और एपीआई आपको IV आकार के उस विकल्प तक सीमित कर सकती है

प्रश्न 3: प्रमाणीकरण टैग हमेशा 16 बाइट्स (128 बिट्स) लंबा है?

नहीं, इसमें 8 बिट वृद्धि के साथ 64 बिट्स से 128 बिट्स तक के बाइट्स में कोई आकार हो सकता है। यदि यह छोटा है तो यह केवल प्रमाणीकरण टैग के बाएं बाइट्स के होते हैं। आप अपने GCMParameterSpec कॉल के लिए GCMParameterSpec तीसरा पैरामीटर के रूप में टैग का एक और आकार निर्दिष्ट कर सकते हैं।

ध्यान दें कि जीसीएम की ताकत टैग के आकार पर दृढ़ता से निर्भर है। मैं इसे 128 बिट्स रखने की सलाह दूंगा। 96 बिट्स न्यूनतम होना चाहिए, खासकर यदि आप बहुत सारे सिफरटेक्स्ट उत्पन्न करना चाहते हैं।

प्रश्न 4: # 2 और # 3 के साथ, और पैडिंग की कमी के साथ, क्या इसका मतलब है कि मेरे एन्क्रिप्टेड संदेश हमेशा 12 + src.length + 16 बाइट लंबे होते हैं? (और इसलिए मैं उन्हें एक बाइट सरणी में सुरक्षित रूप से स्क्विश कर सकता हूं, जिसके लिए मुझे सही लंबाई पता है?)

ऊपर देखो। ओरेकल प्रदाता के लिए यह मामला है। इसके बारे में सुनिश्चित करने के लिए GCMParameterSpec का प्रयोग करें।

प्रश्न 5: क्या उपयोगकर्ताओं के लिए निरंतर स्रोत डेटा दिया गया है, उपयोगकर्ताओं के लिए असंगत संख्या में डेटा डेटा एन्क्रिप्शन प्रदर्शित करना मेरे लिए सुरक्षित है?

वस्तुतः अनबाउंड, हाँ। मैं लगभग 2 ^ 48 एन्क्रिप्शन के बाद चिंता करना शुरू कर दूंगा। सामान्य रूप से आपको मुख्य परिवर्तन के लिए डिज़ाइन करना चाहिए।

प्रश्न 6: क्या मेरे लिए उपयोगकर्ताओं के लिए स्रोत डेटा एन्क्रिप्शन की असंबद्ध संख्या प्रदर्शित करना सुरक्षित है, यदि हर समय src डेटा अलग होता है (उदाहरण के लिए System.currentTimeMillis () या यादृच्छिक संख्याएं)?

Q5 का उत्तर देखें

प्रश्न 7: अगर मैं एन्क्रिप्शन से पहले यादृच्छिक संख्याओं के साथ src डेटा को पैड करता हूं तो क्या इससे मदद मिलेगी? सामने और पीछे 8 यादृच्छिक बाइट्स, या केवल एक छोर पर कहें? या क्या इससे मेरी मदद नहीं होगी / मेरी एन्क्रिप्शन खराब हो जाएगी?

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

मैं जावा 8 में AES/GCM/NoPadding एन्क्रिप्शन का उपयोग कर रहा हूं और मुझे आश्चर्य है कि मेरे कोड में सुरक्षा दोष है या नहीं। मेरा कोड काम करता प्रतीत होता है, जिसमें यह टेक्स्ट को एन्क्रिप्ट और डिक्रिप्ट करता है, लेकिन कुछ विवरण अस्पष्ट हैं।

मेरा मुख्य प्रश्न यह है:

Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] iv = cipher.getIV(); // ?????

क्या वह चतुर्थ "किसी दिए गए कुंजी के लिए, IV को दोहराना नहीं चाहिए" की आवश्यकता को पूरा करता है। आरएफसी 4106 से ?

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

लगभग पूरा कोड है, मोटे तौर पर। अगर मैं इस पोस्ट को लिखते समय त्रुटियों को पेश करता हूं तो मैं क्षमा चाहता हूं:

class Encryptor {
  Key key;

  Encryptor(byte[] key) {
    if (key.length != 32) throw new IllegalArgumentException();
    this.key = new SecretKeySpec(key, "AES");
  }

  // the output is sent to users
  byte[] encrypt(byte[] src) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] iv = cipher.getIV(); // See question #1
    assert iv.length == 12; // See question #2
    byte[] cipherText = cipher.doFinal(src);
    assert cipherText.length == src.length + 16; // See question #3
    byte[] message = new byte[12 + src.length + 16]; // See question #4
    System.arraycopy(iv, 0, message, 0, 12);
    System.arraycopy(cipherText, 0, message, 12, cipherText.length);
    return message;
  }

  // the input comes from users
  byte[] decrypt(byte[] message) throws Exception {
    if (message.length < 12 + 16) throw new IllegalArgumentException();
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    GCMParameterSpec params = new GCMParameterSpec(128, message, 0, 12);
    cipher.init(Cipher.DECRYPT_MODE, key, params);
    return cipher.doFinal(message, 12, message.length - 12);
  }
}

मान लीजिए कि उपयोगकर्ता मेरी गुप्त कुंजी = गेम को क्रैक कर रहे हैं।

अधिक विस्तृत प्रश्न / संबंधित प्रश्न:

  1. क्या चतुर्थ cipher.getIV () द्वारा मेरे लिए इस तरह उपयोग करने के लिए सुरक्षित है?

    • क्या यह चतुर्थ पुन: उपयोग करने की आपदा से बचता है, गैलोइस / काउंटर मोड में महत्वपूर्ण संयोजन?
    • क्या यह अभी भी सुरक्षित है जब मेरे पास एक ही बार में इस कोड को चलाने वाले कई एप्लिकेशन हैं, सभी एक ही स्रोत डेटा (संभवतः एक ही मिलीसेकंड में) से उपयोगकर्ताओं को एन्क्रिप्टेड संदेश प्रदर्शित करते हैं?
    • लौटा हुआ चौथाई क्या है? क्या यह एक परमाणु काउंटर और कुछ यादृच्छिक शोर है?
    • क्या मुझे cipher.getIV() से बचने और अपने स्वयं के काउंटर के साथ खुद को एक चौथाई बनाने की ज़रूरत है?
    • क्या स्रोत कोड cipher.getIV() ऑनलाइन उपलब्ध है, यह मानते हुए कि मैं ओरेकल जेडीके 8 + जेसीई असीमित शक्ति विस्तार का उपयोग कर रहा हूं?
  2. क्या वह चतुर्थ हमेशा 12 बाइट लंबा है?

  3. प्रमाणीकरण टैग हमेशा 16 बाइट्स (128 बिट्स) लंबा है?

  4. # 2 और # 3 के साथ, और पैडिंग की कमी के साथ, क्या इसका मतलब है कि मेरे एन्क्रिप्टेड संदेश हमेशा 12 + src.length + 16 बाइट लंबे होते हैं? (और इसलिए मैं उन्हें एक बाइट सरणी में सुरक्षित रूप से स्क्विश कर सकता हूं, जिसके लिए मुझे सही लंबाई पता है?)

  5. क्या उपयोगकर्ताओं के लिए निरंतर स्रोत डेटा दिया गया है, उपयोगकर्ताओं के लिए असंगत संख्या में डेटा डेटा एन्क्रिप्शन प्रदर्शित करना मेरे लिए सुरक्षित है?

  6. क्या मेरे लिए उपयोगकर्ताओं के लिए src डेटा एन्क्रिप्शन की असंबद्ध संख्या प्रदर्शित करना सुरक्षित है, यदि हर समय src डेटा अलग होता है (उदाहरण के लिए System.currentTimeMillis() या यादृच्छिक संख्याएं)?

  7. अगर मैं एन्क्रिप्शन से पहले यादृच्छिक संख्याओं के साथ src डेटा को गद्दी करता हूं तो क्या इससे मदद मिलेगी? सामने और पीछे 8 यादृच्छिक बाइट्स, या केवल एक छोर पर कहें? या क्या इससे मेरी मदद नहीं होगी / मेरी एन्क्रिप्शन खराब हो जाएगी?

(क्योंकि ये प्रश्न मेरे स्वयं के कोड के समान ब्लॉक के बारे में हैं, और वे एक-दूसरे से दृढ़ता से संबंधित हैं, और अन्य समान कार्यक्षमता को लागू करते समय प्रश्नों का एक ही सेट हो सकते हैं, प्रश्नों को विभाजित करने में गलत लगा पोस्ट। मैं उन्हें अलग-अलग पोस्ट कर सकता हूं अगर यह स्टैक ओवरफ्लो के प्रारूप के लिए अधिक उपयुक्त है। मुझे बताएं!)





aes-gcm