javax.crypto.BadPaddingException: Given final block not properly padded 解决方法

下面的 Des 加密解密代码,在加密时正常,但是在解密是抛出错误:

javax.crypto.BadPaddingException: Given final block not properly padded
        at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
        at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
        at com.sun.crypto.provider.DESCipher.engineDoFinal(DashoA13*..)
        at javax.crypto.Cipher.doFinal(DashoA13*..)

 

public class Des {
    static Des instance;
    static Key key;
    static Cipher encryptCipher;
    static Cipher decryptCipher;

    protected Des() {
    }

    protected Des(String strKey) {
        key = setKey(strKey);
        try {
            encryptCipher = Cipher.getInstance("DES");
            encryptCipher.init(Cipher.ENCRYPT_MODE, key);
            decryptCipher = Cipher.getInstance("DES");
            decryptCipher.init(Cipher.DECRYPT_MODE, key);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }

    }

    public static Des getInstance() {
        if (instance == null) {
            instance = new Des("[email protected]");
        }

        return instance;
    }

    //  根据参数生成KEY
    private Key setKey(String strKey) {
        try {
            KeyGenerator _generator = KeyGenerator.getInstance("DES");
            _generator.init(new SecureRandom(strKey.getBytes()));
            return _generator.generateKey();

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    //  加密String明文输入,String密文输出
    public String setEncString(String strMing) {
        BASE64Encoder base64en = new BASE64Encoder();
        try {
            byte[] byteMing = strMing.getBytes("UTF-8");
            byte[] byteMi = this.getEncCode(byteMing);
            return base64en.encode(byteMi);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //加密以byte[]明文输入,byte[]密文输出
    private byte[] getEncCode(byte[] byteS) {
        byte[] byteFina = null;
        try {
            byteFina = encryptCipher.doFinal(byteS);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return byteFina;
    }

    //	 解密:以String密文输入,String明文输出
    public String setDesString(String strMi) {
        BASE64Decoder base64De = new BASE64Decoder();
        try {
            byte[] byteMi = base64De.decodeBuffer(strMi);
            byte[] byteMing = this.getDesCode(byteMi);
            return new String(byteMing, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 解密以byte[]密文输入,以byte[]明文输出
    private byte[] getDesCode(byte[] byteD) {
        byte[] byteFina = null;
        try {
            byteFina = decryptCipher.doFinal(byteD);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return byteFina;
    }

    //多线程测试一下
    public static void main(String[] args) throws InterruptedException {

        //没有依赖注入的配置,所以在这里手动生成一次
        Des dtDes = Des.getInstance();

        final String[] mi = new String[10];
        for (int i = 0; i < 10; i++) {
            final Integer integer = i;
            Thread thread = new Thread() {
                public void run() {
                    //明文加密:
                    Des dtDes = Des.getInstance();
                    mi[integer] = dtDes.setEncString("ShowHistory.jsp?MenuId=345&MenuBelong=1&tableLimits=where a1450=RecordId"); //调用get函数获取加密后密文。
                }
            };
            thread.start();
        }

        Thread.sleep(5000);

        for (int i = 0; i < 10; i++) {
            final Integer integer = i;

            Thread thread2 = new Thread() {
                public void run() {
                    System.out.println(String.format("mi[%s] = %s", integer, mi[integer]));
                    //这样来模拟另外一个页面的获取
                    Des dtDes2 = Des.getInstance();
                    String M = dtDes2.setDesString(mi[integer]);//调用get函数获取解密后明文。
                    System.out.println(String.format("des[%s] = %s", integer, M));
                }
            };
            thread2.start();
        }

        //等待打印完毕
        Thread.sleep(5000);
    }
}

解决方法:

将 setKey方法修改为如下:

    //  根据参数生成KEY
    private Key setKey(String strKey) {
        try {
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            DESKeySpec keySpec = new DESKeySpec(strKey.getBytes("utf-8"));
            keyFactory.generateSecret(keySpec);
            return keyFactory.generateSecret(keySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

不使用SecureRandom生成SecretKey,而是使用SecretKeyFactory;重新实现方法generateKey,代码如下

问题解决。

时间: 2024-10-13 17:46:45

javax.crypto.BadPaddingException: Given final block not properly padded 解决方法的相关文章

javax.crypto.BadPaddingException: Given final block not properly padded

异常如下 1.javax.crypto.BadPaddingException: Given final block not properly padded 1)要确认下是否加密和解密都是使用相同的填充算法(也就是说,是否都是使用PKCS5Padding)2)确认下你要解密的字节数组是否正确. javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded

javax.crypto.BadPaddingException: Given final block not properly padded解决方案

JAVA的AES加密解密在windows上测试一切正常,上传到空间上在解密时就出现错误.空间是Linux系统 查看日志发现出现此异常 javax.crypto.BadPaddingException: Given final block not properly padded 后面百度了一下终于解决了,在生成key的时候出现错误的 原来的代码: private Key initKeyForAES(String key) throws NoSuchAlgorithmException { if (

记一次文件编码出现的BUG javax.crypto.BadPaddingException: Given final block not properly padded

1.前景:工作中需要实现一个功能,导出的数据需要加密,不能被明文看到,使用DES加密,对byte数组加密解密操作代码如下 public class DESTool { static String transformation = "DESede/ECB/PKCS5Padding"; static String algorithm = "DESede"; public byte[] decode(byte[] srcByte, byte[] keyByte, int

Java 之 Given final block not properly padded

获取Cipher对象的时候一定要写成 Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding"); 不要写成 Cipher cipher = Cipher.getInstance("DES"); 否则解密的时候会报错: Given final block not properly padded 原因是Cipher cipher = Cipher.getInstance("DES");与Ciphe

AES解密异常Given final block not properly padded-在线助手博客

AES 128/192/256位CBC/CFB/ECB/OFB/PCBC 在线加密解密 解密内容:1243CFEBD819AA6B1C717DE870459F7B 秘钥:http://www.it399.com 没有使用填充向量iv AES解密异常Given final block not properly padded javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypt

左右 android AES 所述机器的一部分 javax.crypto.BadPaddingException: pad block corrupted

好多人 android 使用上述 AES 显现 javax.crypto.BadPaddingException: pad block corrupted 下面的代码发布没问题,比较自己.不解释! public static class cryptogram{ public static String encrypt(String seed, String cleartext) throws Exception { byte[] rawKey = getRawKey(seed.getBytes(

关于 android AES 部分机器 javax.crypto.BadPaddingException: pad block corrupted

很多人 android 上面使用 AES 出现 javax.crypto.BadPaddingException: pad block corrupted 下面贴出没有问题的代码,自己对照,不做解释! public static class cryptogram{ public static String encrypt(String seed, String cleartext) throws Exception { byte[] rawKey = getRawKey(seed.getByte

关于javax.crypto.BadPaddingException: Blocktype错误的几种解决方法

关于javax.crypto.BadPaddingException: Blocktype异常的几种解决办法 转载请注明出处 1.异常描述:最近做项目为了增强数据传输的安全性用到了RSA加密.即android客户端将要传送的信息,用私钥通过RSA非对称加密算法加密后,传到服务器端(PC端).服务器端用对应(密钥)的公钥来解密时解密失败,抛出"javax.crypto.BadPaddingException: Blocktype"异常. 2.异常原因:Android系统使用的虚拟机(da

android 上AES解密是报错javax.crypto.BadPaddingException: pad block corrupted

网上看到两种方法: 1.SecretKeySpec skeySpec = new SecretKeySpec(getRawKey(key), "AES"); private static byte[] getRawKey(byte[] seed) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom sr = SecureRandom.getInsta