2013-03-29 8 views
13

जावा में एन्क्रिप्शन \ डिक्रिप्शन को संभालने पर यह बहुत ही बुनियादी, कोड का टुकड़ा काफी आम है।क्रिप्टो अपवादों को संभालना

final Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); 
cipher.init(Cipher.ENCRYPT_MODE, key, iv); 
cipher.doFinal(*something*); 

अकेले इन तीन लाइनों, संभावित छह अपवाद फेंक और मुझे यकीन है कि क्या साफ (कोड पठनीयता के संदर्भ में) जिस तरह से उन्हें संभाल करने के लिए नहीं कर रहा हूँ। छह कैच क्लॉज के साथ प्रयास करें वास्तव में मुझे एक गंध की तरह दिखता है।

क्या ऐसी वस्तुओं के साथ काम करते समय, मैं माइक्रोप्रेटर्न या सर्वोत्तम प्रथाओं को स्पष्ट रूप से याद कर रहा हूं?

संपादित

क्षमा करें, मुझे लगता है कि मैं अपने आप को बहुत अच्छी तरह से नहीं समझा था। मेरा सवाल वास्तव में प्रयास \ पकड़ खंड से बचने के बारे में नहीं है, लेकिन यदि समान स्थितियों को संभालने का एक आम तरीका है।

अपवाद हैं

NoSuchPaddingException, NoSuchAlgorithmException 
InvalidAlgorithmParameterException, InvalidKeyException, 
BadPaddingException, IllegalBlockSizeException 
+0

छः पकड़ने वाले खंडों के साथ प्रयास कोड गंध हो सकता है, लेकिन यह गलत भी नहीं हो सकता है। कोड के इस ब्लॉक से छह अपवाद फेंक सकते हैं? क्या हर कोई इंगित करेगा कि एक अलग मुद्दा हुआ? – Freiheit

+0

एक गैर-विभेदित पकड़ बिल्कुल गंध है। अच्छा प्रश्न +1 –

+0

मैं एक उत्तर दूंगा, लेकिन क्या आप इस प्रश्न में अपवादों को सूचीबद्ध कर सकते हैं? –

उत्तर

15

आप निम्न अपवाद संकेत दिया:

NoSuchPaddingException, NoSuchAlgorithmException 
InvalidAlgorithmParameterException, InvalidKeyException, 
BadPaddingException, IllegalBlockSizeException 

अब इन सब, GeneralSecurityException के हैं तो यह उन सब को पकड़ने के लिए आसान होगा। लेकिन उपयोग के मामले को देखते हुए, शायद आप ऐसा नहीं करना चाहते हैं।

यदि आप अपवादों का कारण देखते हैं तो आप पाएंगे कि इनमें से कोई अपवाद - अंतिम दो को छोड़कर - केवल एल्गोरिदम या कुंजी के क्रियान्वयन को उत्पन्न करते समय फेंक दिया जाता है। मुझे लगता है कि यह उचित है कि एक बार जब आप अपने आवेदन का परीक्षण कर लेंगे कि ये मान कम या ज्यादा स्थिर हैं। इसलिए यह फेंकने के लिए तार्किक होगा - उदाहरण के लिए - IllegalStateExceptionIllegalStateException एक रनटाइम अपवाद है जिसे आपको फेंकने या पकड़ने की आवश्यकता नहीं है। बेशक, आपको अपवाद के के रूप में सुरक्षा अपवाद को इंगित करना चाहिए।

अब पिछले दो अपवाद, BadPaddingException और IllegalBlockSizeException अलग हैं। वे वास्तविक सिफरटेक्स्ट पर निर्भर करते हैं, इसलिए वे एल्गोरिदम के इनपुट पर निर्भर हैं। अब सामान्यतः आपको अपने Cipher उदाहरण में इसे डिक्रिप्शन के लिए शुरू करने से पहले इनपुट की अखंडता को सत्यापित करना चाहिए, उदाहरण के लिए पहले एचएमएसी चेकसम को मान्य करना)। तो उस अर्थ में आप अभी भी रनटाइम अपवाद से दूर हो सकते हैं।

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

Cipher और डिक्रिप्शन के निर्माण और प्रारंभ के लिए अलग try/catch ब्लॉक का उपयोग करना संभवतः संभव है। GeneralSecurityException को संभालने से पहले आप BadPaddingException और IllegalBlockSizeException अपवाद भी प्राप्त कर सकते हैं। जावा 7 से शुरू करने से आप बहु-पकड़ विवरण भी उपयोग कर सकते हैं (उदा। catch(final BadPaddingException | IllegalBlockSizeException e))।


अंत में कुछ नोट:

  • खबरदार है कि एक अपवाद एईएस कुंजी आकार 192 बिट और 256 बिट अगर असीमित क्रिप्टो फ़ाइलें स्थापित नहीं किया जा रहा है (जाँच अधिक जानकारी के लिए Oracle JavaSE site) के लिए फेंक दिया जा सकता है ; आपको जांचना चाहिए कि आवेदन शुरू होने पर कुंजी आकार की अनुमति है या नहीं;
  • BadPaddingException और IllegalBlockSizeException दोनों हमलों के कारण बनाए जा सकते हैं या क्योंकि डेटा पूरी तरह से मौजूद नहीं था;
  • BadPaddingException भी कुंजी गलत होने पर फेंक दिया जा सकता है।
+0

+1। –

+0

स्वागत के लिए और इस उत्तर के लिए धन्यवाद। मुझे यही चाहिए! –

-1

कि संभाल करने के लिए सबसे अच्छा तरीका है एक bussines अपवाद (MyModuleException या कुछ और) और फिर rethrow कि अपवाद क्रिप्टो अपवाद जोड़ने हिस्सा पैदा करने के लिए तैयार करना है। इस तरह आपकी विधि केवल एक अपवाद फेंक देगी, छः नहीं, आपके आवेदन की अन्य परतों में प्रबंधन करना कितना आसान होगा।

public void myMethod(...) throws MyModuleException { 
    try { 
    final Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); 
    cipher.init(Cipher.ENCRYPT_MODE, key, iv); 
    cipher.doFinal(*something*); 
    } catch(Crypto1Ex ex){ 
    throw new MyModuleException("something is wrong", ex); //ex added, so it is not lost and visible in stacktraceses 
    } catch(Crypto1Ex ex){ 
    throw new MyModuleException("something is wrong", ex); 
    } //etc. 
} 

जावा 7 में आप को संभाल सकता है यह और भी आसान (देखें: http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html)

+0

इस समय मैं कम या ज्यादा कर रहा हूं। दुर्भाग्यवश मैं Java7 सुविधाओं का उपयोग नहीं कर सकता या यह वही तरीका होगा जो मैं लेता हूं। प्लेटफ़ॉर्म सुविधा समस्याओं से प्रोग्राम इनपुट समस्याओं को अलग करने के लिए –

2

आप कुछ specificty कम करने के लिए तैयार हैं, तो क्रिप्टो अपवाद के सभी का विस्तार GeneralSecurityException, तो आप उस बजाय पकड़ कर सकते हैं।

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