Android DES Decrypt badpaddingexception:pad块损坏

时间:2012-08-24 13:33:30

标签: android encryption des

首先,我已经审查了论坛上的所有条目,但我仍然无法找到问题的解决方案。 我必须测量用DES编码和解码文本所花费的时间,并与其他算法进行比较。

当我运行代码时,出现此错误: BadPaddingException:pad block corrupted 。当我调试时,代码在此行中失败:

byte [] plaintext = cipher.doFinal(cipherBytes);

我使用类Base64对String< - >进行编码/解码字节[]

有什么想法吗?

感谢

private static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";
private static int KEY_LENGTH = 64;

 public static SecretKey deriveKeyDES() {
        try {
            long start = System.currentTimeMillis();

            KeyGenerator kgen = KeyGenerator.getInstance("DES");
            kgen.init(KEY_LENGTH);
            SecretKey result = kgen.generateKey();

            long elapsed = System.currentTimeMillis() - start;
            return result;

        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        } 
    }


    public static String encrypt(String plaintext, SecretKey key) {
        try {

            long start = System.currentTimeMillis();
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding")

            cipher.init(Cipher.ENCRYPT_MODE, key);

            byte[] cipherText = cipher.doFinal(plaintext.getBytes("UTF-8"));

            long elapsed = System.currentTimeMillis() - start;

            return toBase64(cipherText);

        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String toBase64(byte[] bytes) {
        return Base64.encodeToString(bytes, Base64.NO_WRAP).trim();
    }


    public static String decrypt(String ciphertext, SecretKey key) {
        try {
            byte[] cipherBytes = fromBase64(ciphertext);

                long start = System.currentTimeMillis();
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

            cipher.init(Cipher.DECRYPT_MODE, key);
            cipher.update(cipherBytes);

             // This is where I get exception
            byte[] plaintext = cipher.doFinal(cipherBytes);

            String plainrStr = new String(plaintext, "UTF-8").trim();
            long elapsed = System.currentTimeMillis() - start;

            return plainrStr;
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] fromBase64(String base64) {
        return Base64.decode(base64, Base64.NO_WRAP);
    }

3 个答案:

答案 0 :(得分:1)

Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

cipher.init(Cipher.DECRYPT_MODE, key);
cipher.update(cipherBytes);

// byte[] plaintext = cipher.doFinal(cipherBytes);
//                                   ^-- You shouldn't pass cipherBytes twice.
//                                   v-- instead use the parameter-less method:
byte[] plaintext    = cipher.doFinal();

答案 1 :(得分:1)

当最后一个密文块不计算为有效的纯文本时,会发生填充异常。如果最后一个密文块被破坏或密钥不正确,就会发生这种情况。对于CBC模式,如果倒数第二个密文被更改(但您使用的是ECB模式加密),也会发生这种情况。

在您的情况下,deriveKeyDES()始终生成随机密钥。虽然我们没有得到对安全方法的实际调用,但我会推测您使用不同的密钥进行加密和解密。在这种情况下,生成的纯文本很可能不包含有效的填充字节。

Rasmus回答肯定会指出代码中的错误,它会搞砸你的时间并返回纯文本两次,但它不会删除BadPaddingException

答案 2 :(得分:0)

我在一个源代码中遇到了同样的问题,而在另一个源代码中遇到了IllegalBlockSizeException。 通过返回编码数据解决了这两个问题,如:

 public String encrypt(String input) {
    try {
        byte[] inputBytes = input.getBytes("UTF-8");
        byte[] enc = encryptCipher.doFinal(inputBytes);
        // and problem was in return encoding. That's how i fixed it 
        return Base64.encodeToString(enc,Base64.DEFAULT);
        .....
          }
        }

给你一个解密代码:

 public String decrypt(String input) {
    try {
        byte[] dec = Base64.decode(input.getBytes(), Base64.DEFAULT);
        //here had exception
        byte[] utf8 = decryptCipher.doFinal(dec);
        return new String(utf8,"UTF8");
    } catch (IOException | BadPaddingException | IllegalBlockSizeException e) {
        e.printStackTrace();
    }
    return null;
}

我应该提交,它有BadPaddingException和IllegalBlockSizeException 只在解密方法 byte [] utf8 = decryptCipher.doFinal(dec); (你在同一个地方有一个例子: < em> byte [] plaintext = cipher.doFinal(cipherBytes); ),但真正的错误在于加密方法(返回值)

这就是我建议您在加密方法中使用该代码的原因:

return Base64.encodeToString(enc,Base64.DEFAULT);

P.S试图在你的问题上给出完整答案。