2014-04-14 7 views
5

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

javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) at com.sun.crypto.provider.DESCipher.engineDoFinal(DashoA13*..) at javax.crypto.Cipher.doFinal(DashoA13*..) at...

यहाँ मेरी कोड है:

public static PrivateKey readPrivateKeyFromFile(File file, String chaveSecreta) { 
    try { 
     SecureRandom r = new SecureRandom(chaveSecreta.getBytes()); 
     KeyGenerator keyGen = KeyGenerator.getInstance("DES"); 
     keyGen.init(56, r); 
     Key key = keyGen.generateKey(); 

     byte[] privateKeyBytes = decryptPKFile(file, key); 

     KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
     EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes); 
     PrivateKey privateKey = null; 
     try { 
      privateKey = keyFactory.generatePrivate(privateKeySpec); 
     } catch (InvalidKeySpecException e) { 
      JOptionPane.showMessageDialog(null, "Erro 01, tente mais tarde"); 
     } 
     return privateKey; 
    } catch (NoSuchAlgorithmException e) { 
     JOptionPane.showMessageDialog(null, "Erro 02, tente mais tarde"); 
    } 
    return null; 
} 

public static byte[] decryptPKFile(File file, Key key){ 
    try{ 
     Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
     byte[] cipherText = readBytes(file); 
     cipher.init(Cipher.DECRYPT_MODE, key); 
     System.out.println(cipher); 
     System.out.println(cipherText); 
     byte[] text = cipher.doFinal(cipherText); 
     return text; 
    }catch(Exception e){ 
     e.printStackTrace(); 
     return null; 
    } 
} 

public static byte[] readBytes(File file) { 
    try { 
     FileInputStream fs = new FileInputStream(file); 
     byte content[] = new byte[(int) file.length()]; 
     fs.read(content); 
     return content; 
    } catch (FileNotFoundException e) { 
     System.out.println("Arquivo não encontrado!"); 
     e.printStackTrace(); 
    } catch (IOException ioe) { 
     System.out.println("Erro ao ler arquivo!"); 
     ioe.printStackTrace(); 
    } 
    return null; 
} 

किसी भी syggestions?

+0

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

+2

आपका मतलब 8 से अधिक है? यह है, फ़ाइल दूषित नहीं है, मैंने जांच की है। –

+0

@markubik यह एक यादृच्छिक कुंजी है: पी –

उत्तर

8

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

आपको SecretKeyFactoryKeyGenerator नहीं उपयोग करने की आवश्यकता है। और आपको निश्चित रूप से 8-बाइट कुंजी डेटा की आवश्यकता होगी। अपने मामले में इसे पुनर्प्राप्त करने का एकमात्र तरीका SecureRandom एल्गोरिदम/कार्यान्वयन को कुंजी से पहले और फिर से गणना करना है।

अब कोई भी सिफरटेक्स्ट किसी भी कुंजी के साथ डिक्रिप्ट करेगा। डीईएस ईसीबी केवल (कुछ प्रकार की) गोपनीयता प्रदान करता है, अखंडता नहीं। समस्या यह है कि यह कूड़ेदान में डिक्रिप्ट होगा। अब यदि आप कचरे से पैडिंग को हटाने का प्रयास करते हैं तो आपको एक पैडिंग त्रुटि मिल जाएगी।

यदि आप "भाग्यशाली" हैं - एक बार लगभग 256 बार - आपको परिणाम मिल जाएगा। ऐसा तब होता है जब डिक्रिप्ट ब्लॉकया 0202 के साथ समाप्त होता है, यह वैध पैडिंग है। नतीजा - निश्चित रूप से - कचरा भी होगा, लेकिन यह BadPaddingException के साथ समाप्त नहीं होगा। आपके मामले में SecureRandom उदाहरण संभावित है, वही गलत मान वापस करने के लिए हालांकि, ऐसा कभी नहीं हो सकता है।

भविष्य में, कृपया पीबीकेडीएफ 2 का उपयोग करें और इसे एन्कोडेड पासवर्ड फ़ीड करें। स्पष्ट रूप से वर्णित वर्ण एन्कोडिंग नोट करें, जावा एसई चार सरणी के निम्नतम 8 बिट्स का उपयोग करता है। कभी भी String.getBytes() का उपयोग न करें क्योंकि सिस्टम के बीच डिफ़ॉल्ट एन्कोडिंग भिन्न हो सकती है।

+1

पुhew, कई संपादनों के लिए खेद है, देर हो रही है। –

+2

मुझे लगता है कि यह मेरे सिस्टम की वजह से है। विंडोज़ का उपयोग करते समय सबकुछ काम करता है, लेकिन यह मेरे मैक पर काम नहीं करेगा। मान लीजिए कि यह String.getBytes() चीज है जो आपने कहा .. –

+1

http://stackoverflow.com/questions/9312816/java-platforms-default-charset-on- अलग- प्लेटफार्म –

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