2017-02-16 290 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),这个错误可能只是意味着你已经提供了按错键。

相关问题