2009-08-04 15 views
8

मैं जावा सिफर और एईएस का उपयोग करके एन्क्रिप्शन/डिक्रिप्शन लागू कर रहा हूं। सबकुछ अच्छी तरह से काम कर रहा है सिवाय इसके कि कॉल करने के लिए कॉल पर लिखे गए 5 अतिरिक्त बाइट्स हैं()। तो, मैं एक अतिरिक्त डीकोडेड स्ट्रिंग के साथ समाप्त होता हूं जिसमें 5 अतिरिक्त बाइट संलग्न होते हैं।जावा cipher.doFinal() अतिरिक्त बाइट्स लिखना

मेरा मानना ​​है कि कारण यह है कि 16-बाइट्स का पूरा ब्लॉक लिखा जा रहा है। मैं 3 16-बाइट ब्लॉक देखता हूं, जिसमें अंतिम एक भी शामिल है। इनपुट एन्क्रिप्टेड फ़ाइल 64-बाइट्स है। अनएन्क्रिप्टेड टेक्स्ट 43 बाइट होना चाहिए।

डोफिनल के लिए प्रलेखन इंगित करता है कि यह आउटपुट बफर को लिखे गए बाइट्स की संख्या वापस कर सकता है। हालांकि, यह 0,16,16,16 है। मैंने हर प्रकार के कामकाज और अद्यतन की कोशिश की है और व्यवहार में कोई बदलाव नहीं आया है।

यह समझ में आता है कि यह एक पूर्ण-ब्लॉक लिख रहा है, क्योंकि इस तरह के अधिकांश एल्गोरिदम संचालित होते हैं। हालांकि, अगर यह मुझे आउटपुट डेटा का आकार नहीं बताएगा, तो मुझे अतिरिक्त डेटा को कैसे रोकना चाहिए?

शायद मुझे एक और एल्गोरिदम का उपयोग करना चाहिए? एईएस 256 एक आवश्यकता है, लेकिन मुझे आश्चर्य है कि एक अलग ब्लॉक प्रकार या पैडिंग प्रकार इसे बाइट्स की सही संख्या लिखने की अनुमति दे सकता है।

कोई मार्गदर्शन?

के लिए (कुछ) संक्षिप्तता कतरना:

decryptCipher = Cipher.getInstance("AES"); 
decryptCipher.init(Cipher.DECRYPT_MODE, aesKey); 

डिक्रिप्शन दिनचर्या के व्यापार हिस्सा।

long bytesToRead = inputFile.length(); 

    while ((inLen = in.read(buffer)) > 0) { 
     int bytesOut = 0; 
     byte[] cryptBytes = null; 
     int outLen = cipher.getOutputSize(inLen); 
     cryptBytes = new byte[outLen]; 

     if (bytesToRead <= buffer.length) { 
      try { 
       bytesOut = cipher.doFinal(buffer, 0, inLen, cryptBytes, 0); 
      } catch (ShortBufferException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } else 
      try { 
       bytesOut = cipher.update(buffer, 0, inLen, cryptBytes, 0); 
      } catch (ShortBufferException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     out.write(cryptBytes, 0, bytesOut); 
     bytesToRead -= inLen; 

    } 
    try { 
     out.flush(); 
     in.close(); 
     out.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

उत्तर

14

जब आप Cipher.getInstance() को कॉल करते हैं तो आपको एक पैडिंग तंत्र निर्दिष्ट करना होगा - जाहिर है यह दोनों एन्क्रिप्शन और डिक्रिप्शन समय पर समान होना चाहिए। उदाहरण के लिए:

decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

एक गद्दी तंत्र के बिना, डिक्रिप्शन तरफ जहां प्लेन टेक्स्ट के अंत (पिछले ब्लॉक के भीतर) है कोई जानकारी नहीं है।

+0

बहुत बढ़िया, बहुत बहुत धन्यवाद। यह हल हो गया। मैं इस धारणा के तहत था कि अगर आपने केवल एईएस निर्दिष्ट किया है, तो आपको डिफ़ॉल्ट रूप से ईसीबी ब्लॉक मोड और पीसीके 5 पैडिंग मिलती है। मान लीजिए कि यह गलत है। – wadesworld

+1

यह सभी एईएस इंजनों पर लागू होता है, जिनमें जावा में नहीं है। – Cheeso

1

एईएस एक ब्लॉक सिफर है, स्वाभाविक रूप से यह आप पूरे ब्लॉक देने के लिए, के रूप में होगा सभी ब्लॉक सिफर रहा है।

अधिक जानकारी के लिए Wikipedia article on AES देखें।

आपने कहा था कि आप इसे "बाइट्स की सही संख्या" आउटपुट करना चाहते हैं। आपने कैसे तय किया है कि बाइट्स की सही संख्या क्या है?

+1

मुझे लगता है कि वह जानता है कि एईएस ऐसा करता है, सवाल जावा एपीआई का उपयोग करने के बारे में है। – skaffman

+0

डिक्रिप्ट करने के बाद सही अनएन्क्रिप्टेड आकार को जानने के लिए उसे मूल आकार को स्ट्रीम में लिखना चाहिए। –

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