java aes javax.crypto.BadPaddingException:给定最终块未正确填充

时间:2014-10-23 14:04:12

标签: java encryption nullpointerexception aes

public class AES {

    public String getEncrypt(String pass){
        String password = encrypt(pass);
        return password;
    }

    public String getDecrypt(String pass){
        String key = "AesSEcREtkeyABCD";
        byte[] passwordByte = decrypt(key,pass);
        String password = new String(passwordByte);
        return password;
    }

    private byte[] decrypt(String key, String encrypted) {
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(skeySpec.getEncoded(), "AES"));
            //getting error here
            byte[] original = cipher.doFinal(encrypted.getBytes());
            return original;
        } catch (IllegalBlockSizeException ex) {
            ex.printStackTrace();
        } catch (BadPaddingException ex) {
            ex.printStackTrace();
        } catch (InvalidKeyException ex) {
            ex.printStackTrace();
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } catch (NoSuchPaddingException ex) {
            ex.printStackTrace();
        }
        return null;
    } 

    private String encrypt(String value) {
        try {
            byte[] raw = new byte[]{'A', 'e', 's', 'S', 'E', 'c', 'R', 'E', 't', 'k', 'e', 'y','A','B','C','D'};
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            byte[] encrypted = cipher.doFinal(value.getBytes());
            System.out.println("encrypted string:" + (new String(encrypted)));
            return new String(encrypted);
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } catch (IllegalBlockSizeException ex) {
            ex.printStackTrace();       
        } catch (BadPaddingException ex) {
            ex.printStackTrace();
        } catch (InvalidKeyException ex) {
            ex.printStackTrace();
        } catch (NoSuchPaddingException ex) {
            ex.printStackTrace();
        }
        return null;
    }

** 每当我解密时,我都有一个空指针。有时它给了我正确的解密密码,但有时它给了我一个空指针。无法猜出问题在这里**

1 个答案:

答案 0 :(得分:8)

您正在混合字符串和字节数组。这并不总是一件好事。至少指定您用于字节到字符转换的字符集。即使这样,它也不是100%安全的。最好将字符串视为字符串,将字节数组视为字节数组。

如果这不能解决问题,那么很多事情都会导致“填充不良”问题。错误。基本上任何导致最后一个块结束不匹配预期填充的东西都会引发错误。可能的原因包括:填充设置不正确,密钥错误,密文错误等。

要尝试诊断问题,请将解密端设置为NoPadding。这将接受任何内容,并允许您检查输出:

  • 完全垃圾:您可能在密钥或不同模式设置中出错。

  • 第一次阻止垃圾:您可能遇到密钥错误或IV错误。

  • 最后一个块垃圾:可能是cyphertext文件的损坏结束。

  • 正确的解密,最后有一些奇怪的字节:奇怪的字节是填充。

如果它只是填充,那么设置解密函数以期望这种填充。否则,检查加密和解密的密钥/ IV / cyphertext byte-to-byte 是否相同。

至关重要您在诊断后设置了填充模式。 NoPadding是不安全的。