2017-02-16 42 views
0

注意:根據接受的答案,這只是提供錯誤鍵的問題。如果它對其他人有用,我已經在下面留下了代碼和最初的問題。給定最後的塊沒有正確填充BadPaddingException來自Cipher.doFinal DES

=======

我已經加密了一年一些文本半前和現在我無法解密。它工作(然後我知道字符串本身沒有改變),但現在我得到了「給定的最終塊沒有正確填充」BadPaddingException。

下面是用加密的字符串,鑰匙,和我當時所使用的代碼一個獨立的程序:

import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.DESKeySpec; 

import sun.misc.BASE64Decoder; 
import sun.misc.BASE64Encoder; 


public class DoDecode { 
    private static final String DES_TYPE = "DES"; 
// private static final String DES_TYPE = "DES/CBC/NoPadding"; 
// private static final String DES_TYPE = "DES/CBC/PKCS5Padding"; 
// private static final String DES_TYPE = "DES/ECB/NoPadding"; 
// private static final String DES_TYPE = "DES/ECB/PKCS5Padding"; //Use this 
// private static final String DES_TYPE = "DESede/CBC/NoPadding"; 
// private static final String DES_TYPE = "DESede/CBC/PKCS5Padding"; 
// private static final String DES_TYPE = "DESede/ECB/NoPadding"; 
// private static final String DES_TYPE = "DESede/ECB/PKCS5Padding"; 

    public synchronized static String encode(String unencodedString, String key) { 
     String ret = null; 

     try { 
      DESKeySpec keySpec = new DESKeySpec(key.getBytes("UTF8")); 
      SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 
      SecretKey skey = keyFactory.generateSecret(keySpec); 
      sun.misc.BASE64Encoder base64encoder = new BASE64Encoder(); 

      byte[] cleartext = unencodedString.getBytes("UTF8"); 

      Cipher cipher = Cipher.getInstance(DES_TYPE); 
      cipher.init(Cipher.ENCRYPT_MODE, skey); 

      ret = base64encoder.encode(cipher.doFinal(cleartext)); 
     } catch (Exception ex) { 
      System.err.println("Encode exception: "+ex.getMessage()); 
     } 

     return ret; 
    } 

    public static String decode(String encodedString, String key) { 
     String ret = null; 

     try { 
      DESKeySpec keySpec = new DESKeySpec(key.getBytes("UTF8")); 
      SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 
      SecretKey skey = keyFactory.generateSecret(keySpec); 
      sun.misc.BASE64Decoder base64decoder = new BASE64Decoder(); 

      byte[] encrypedPwdBytes = base64decoder.decodeBuffer(encodedString); 

      Cipher cipher = Cipher.getInstance(DES_TYPE); 
      cipher.init(Cipher.DECRYPT_MODE, skey); 
      byte[] plainTextPwdBytes = (cipher.doFinal(encrypedPwdBytes)); 

      ret = new String(plainTextPwdBytes); 
     } catch (Exception ex) { 
      System.err.println("Decode exception: " + ex.getMessage()); 
     } 

     return ret; 
    } 

    private static final String wasValidStr = "h1JTFcRjW6vveQUrQqPUgnjGXo3NEZKDnBThZQN7uLfzPEpeFFONV4mvL71cT/xQb1mz5Xa/XZ/aW2GawZNumgO0reUZSDh30F7NfK0S/rMWM8FxcjBCkfFWAbLZHcyDJ5wW3F1yl5g="; 

    public static void main(String[] args) { 
     System.out.println(DoDecode.decode(wasValidStr, "invpwd~~")); 

     String encoded = DoDecode.encode("This has worked in the past!", "invpwd~~"); 
     System.out.println(encoded); 
     System.out.println(DoDecode.decode(encoded, "invpwd~~")); 
    } 
} 

給我的輸出:

Decode exception: Given final block not properly padded 
null 
U3ruztxHelQegTLyyA3IfMaGgVtmbP5na43S9JQmIc8= 
This has worked in the past! 

注意,我恢復了碼我曾經使用過,因爲它可能是一個罪魁禍首。我目前沒有使用Base64的sun.misc軟件包,並且得到相同的錯誤(java.util.Base64)。

我在Linux,Mac和PC上試過這個,結果相同。我利用多個JDK版本返回到Java 1.6u45。我還使用類頂部的每個不同DES_TYPE運行示例代碼。

任何幫助,非常感謝!

+0

有你也有多個版本的JRE試了一下,因爲那是纔是最重要的? –

+1

一般建議:**總是使用完全合格的Cipher字符串**'Cipher.getInstance(「DES」);'可能導致不同的密碼,這取決於默認的安全提供程序,最有可能導致'「DES/ECB/PKCS5Padding」 ,但並不一定如果它改變了,你將失去不同JVM之間的兼容性。參考:[Java default Crypto/AES behavior](http://stackoverflow.com/q/6258047/1816580) –

+0

感謝您的評論。我已更新我的代碼以反映我今天嘗試的不同密碼字符串(不幸的是,原始代碼僅適用於sp明確的「DES」)。是的,我通過在Eclipse中設置Java構建路徑,重建和運行,嘗試了不同的JRE。 –

回答

0

我追蹤到答案。密鑰實際上是不正確的。錯誤信息非常混亂,以至於我一直在追逐異常的更爲複雜的原因。當我終於崩潰並嘗試其他歷史鑰匙時,一個神奇地解鎖了一切。 :(

所以(其他職位已highlighed),這個錯誤可能只是意味着你已經提供了按錯鍵。

相關問題