开发者社区> 问答> 正文

AES解密失败:Given final block not properly p?报错

AES解密失败:Given final block not properly padded. Such issues can arise if a bad key is used during decryption.? 400 报错

javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption. at java.base/com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:975) at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1056) at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853) at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446) at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202) at net.ooquan.institute.util.AESEncryptUtil.decryptAES(AESEncryptUtil.java:65) at net.ooquan.institute.util.AESEncryptUtil.main(AESEncryptUtil.java:32)

AES解密的时候出错了,加密解密放在一起是没有问题的,但是分开单独一个方法就GG了,求救
------------

代码如下:

public class AESEncryptUtil {

    private static byte[] salt =
        {(byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c, (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99};

    public static void main(String[] args) throws Exception {

        // 加密字符串
        String message = "df723820";
        String password = "8679270339387350";

        String a = encryptAES(message, password);
        decryptAES(a, password);
    }

    public static String encryptAES(String message, String password) throws Exception {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secret);

        byte[] ciphertext = cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
        String result = Hex.encodeHexString(ciphertext).toString();
        System.out.println("加密后: " + result);

        byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
        byte[] decryptStr = cipher.doFinal(Hex.decodeHex(result));
        System.out.println("同一个class里解密: " + new String(decryptStr, StandardCharsets.UTF_8));
        return result;
    }

    public static void decryptAES(String message, String password) {
        try {
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
            cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
            byte[] decryptStr = cipher.doFinal(Hex.decodeHex(message));
            String result = new String(decryptStr, StandardCharsets.UTF_8);
            System.out.println("不同一个class里解密: " + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行结果:

展开
收起
爱吃鱼的程序员 2020-06-22 23:03:52 3121 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    IV没有设置对。

    加解密的IV需要设置成一个

    ######

    引用来自“郭里奥”的评论

    IV没有设置对。

    加解密的IV需要设置成一个

    CBC加密模式需要初始向量iv,并且在加/解密的时候一直就OK了

    需要有一定的密码学基础。

    然后推荐下自己封装的加解密的工具包

    https://github.com/guoliao502/crypto

    2020-06-22 23:04:11
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载