【问题标题】:Given final block not properly padded BadPaddingException from Cipher.doFinal DES给定最终块未正确填充来自 Cipher.doFinal DES 的 BadPaddingException
【发布时间】:2017-02-16 06:05:52
【问题描述】:

注意:根据接受的答案,这只是提供错误密钥的问题。如果对其他人有用,我已将代码和初始问题留在下面。

=======

大约一年半前我加密了一些文本,现在我无法解密它。它当时起作用了(我知道字符串本身没有改变),但现在我得到一个“给定的最终块没有正确填充”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 运行示例代码。

非常感谢任何帮助!

【问题讨论】:

  • 您是否也尝试过使用多个 JRE 版本,因为这很重要?
  • 一般建议:始终使用完全限定的密码字符串。 Cipher.getInstance("DES"); 可能会产生不同的密码,具体取决于默认的安全提供程序。它最有可能导致"DES/ECB/PKCS5Padding",但并非必须如此。如果它发生变化,您将失去不同 JVM 之间的兼容性。供参考:Java default Crypto/AES behavior
  • 感谢 cmets。我已经更新了我的代码以反映我今天尝试的不同密码字符串(不幸的是,原始代码只指定了“DES”)。是的,我通过在 Eclipse 中设置 Java 构建路径、重新构建和运行来尝试使用不同的 JRE。

标签: java exception encryption des


【解决方案1】:

我找到了答案。密钥实际上是不正确的。错误消息是如此令人困惑,以至于我一直在寻找更复杂的异常原因。当我终于崩溃并尝试其他历史钥匙时,一个神奇地解锁了一切。 :(

所以(正如其他帖子所强调的那样),这个错误可能只是意味着您提供了错误的密钥。

【讨论】:

    猜你喜欢
    • 2015-07-01
    • 2014-05-29
    • 2014-01-22
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 2011-12-24
    相关资源
    最近更新 更多