javax.crypto.BadPaddingException:给定的最后一个块在修补WebSphere后未正确填充

javax.crypto.BadPaddingException:给定的最后一个块在修补WebSphere后未正确填充,java,encryption,websphere,Java,Encryption,Websphere,嗯,这不是一个新程序,我没有对有问题的部件做任何更改。 我的系统管理员刚刚将IBM WebSphere Application Server从8.5.0.1修补到8.5.5.4。 我过去加密过很多文件。但升级完成后,我无法再解密这些文件。 我确信我使用的是相同的方法和密钥,因为它们在我的程序中都是硬编码的。而且我没有更改任何相关代码。 这里是错误 javax.crypto.BadPaddingException: Given final block not properly padded at

嗯,这不是一个新程序,我没有对有问题的部件做任何更改。
我的系统管理员刚刚将IBM WebSphere Application Server从8.5.0.1修补到8.5.5.4。
我过去加密过很多文件。但升级完成后,我无法再解密这些文件。
我确信我使用的是相同的方法和密钥,因为它们在我的程序中都是硬编码的。而且我没有更改任何相关代码。

这里是错误

javax.crypto.BadPaddingException: Given final block not properly padded
at com.ibm.crypto.provider.AESCipher.engineDoFinal(Unknown Source)
at com.ibm.crypto.provider.AESCipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(Unknown Source)
at com.xxx.framework.core.common.util.CipherUtil.crypt(CipherUtil.java:175)
at com.xxx.framework.core.common.util.CipherUtil.decrypt(CipherUtil.java:102)
at com.xxx.framework.core.common.util.ZipCipherUtil.decryptUnzip(ZipCipherUtil.java:84)
at xxx(xxx.java:2894)
at xxx(xxx.java:748)
at xxx(xxx.java:727)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at yyy(ActionProxy.java:54)
我删除了一些部分,因为其中包含一些敏感的业务信息
这就是代码

CipherUtil.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class CipherUtil {
    private static String type = "AES";

    private static final String HEXES = "0123456789ABCDEF";

    public void encrypt(String srcFile, String destFile, String privateKey) throws GeneralSecurityException, IOException {
        Key key = getKey(privateKey);
        Cipher cipher = Cipher.getInstance(type + "/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(mkdirFiles(destFile));

            crypt(fis, fos, cipher);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw e;
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (fis != null) {
                fis.close();
            }
            if (fos != null) {
                fos.close();
            }
        }
    }

    public void decrypt(String srcFile, String destFile, String privateKey) throws GeneralSecurityException, IOException {
        Key key = getKey(privateKey);
        Cipher cipher = Cipher.getInstance(type + "/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(mkdirFiles(destFile));

            crypt(fis, fos, cipher);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw e;
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (fis != null) {
                fis.close();
            }
            if (fos != null) {
                fos.close();
            }
        }
    }

    private static Key getKey(String secret) throws GeneralSecurityException {
        KeyGenerator kgen = KeyGenerator.getInstance(type);
        kgen.init(128, new SecureRandom(secret.getBytes()));
        SecretKey secretKey = kgen.generateKey();
        return secretKey;
    }

    private static void crypt(InputStream in, OutputStream out, Cipher cipher) throws IOException, GeneralSecurityException {
        int blockSize = cipher.getBlockSize() * 1000;
        int outputSize = cipher.getOutputSize(blockSize);

        byte[] inBytes = new byte[blockSize];
        byte[] outBytes = new byte[outputSize];

        int inLength = 0;
        boolean more = true;
        while (more) {
            inLength = in.read(inBytes);
            if (inLength == blockSize) {
                int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
                out.write(outBytes, 0, outLength);
            } else {
                more = false;
            }
        }
        if (inLength > 0)
            outBytes = cipher.doFinal(inBytes, 0, inLength);
        else
            outBytes = cipher.doFinal();
        out.write(outBytes);
    }

    public String encryptString(String srcString, String keyString) throws GeneralSecurityException {
        Key key = getKey(keyString);
        Cipher cipher = Cipher.getInstance(type + "/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);

        byte[] coded = cipher.doFinal(srcString.getBytes());

        return byteArrayToHexString(coded);
    }   

    public String decryptString(String srcString, String keyString) throws GeneralSecurityException {
        Key key = getKey(keyString);
        Cipher cipher = Cipher.getInstance(type + "/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);

        byte[] decoded = cipher.doFinal(hexStringToByteArray(srcString));

        return new String(decoded);
    }


    private String byteArrayToHexString(byte[] raw) 
    {
        if (raw == null) 
        {
            return null;
        }

        final StringBuilder hex = new StringBuilder(2 * raw.length);

        for (final byte b : raw) 
        {
            hex.append(HEXES.charAt((b & 0xF0) >> 4))
                .append(HEXES.charAt((b & 0x0F)));
        }
        return hex.toString();
    }

    public static byte[] hexStringToByteArray(String s) {
        if (s == null || (s.length() % 2) == 1)
        {
           throw new IllegalArgumentException();
        }

        final char[] chars = s.toCharArray();
        final int len = chars.length;
        final byte [] data = new byte [len / 2];

        for (int i=0; i<len; i+=2) 
        {
           data[i / 2] = (byte) ((Character.digit (chars[i], 16) << 4) + Character.digit (chars[i + 1], 16));
        }
        return data;
    }   
}
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileNotFoundException;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStream;
导入java.security.GeneralSecurityException;
导入java.security.Key;
导入java.security.SecureRandom;
导入javax.crypto.Cipher;
导入javax.crypto.KeyGenerator;
导入javax.crypto.SecretKey;
公共类密码{
私有静态字符串type=“AES”;
私有静态最终字符串HEXES=“0123456789ABCDEF”;
public void encrypt(String srcFile、String destFile、String privateKey)引发GeneralSecurityException、IOException{
Key=getKey(privateKey);
Cipher Cipher=Cipher.getInstance(type+“/ECB/PKCS5Padding”);
cipher.init(cipher.ENCRYPT_模式,密钥);
FileInputStream fis=null;
FileOutputStream=null;
试一试{
fis=新文件输入流(srcFile);
fos=新文件输出流(mkdirFiles(destFile));
密码(fis、fos、密码);
}catch(filenotfounde异常){
e、 printStackTrace();
投掷e;
}捕获(IOE异常){
e、 printStackTrace();
投掷e;
}最后{
如果(fis!=null){
fis.close();
}
如果(fos!=null){
fos.close();
}
}
}
public void decrypt(String srcFile、String destFile、String privateKey)抛出GeneralSecurityException、IOException{
Key=getKey(privateKey);
Cipher Cipher=Cipher.getInstance(type+“/ECB/PKCS5Padding”);
cipher.init(cipher.DECRYPT_模式,密钥);
FileInputStream fis=null;
FileOutputStream=null;
试一试{
fis=新文件输入流(srcFile);
fos=新文件输出流(mkdirFiles(destFile));
密码(fis、fos、密码);
}catch(filenotfounde异常){
e、 printStackTrace();
投掷e;
}捕获(IOE异常){
e、 printStackTrace();
投掷e;
}最后{
如果(fis!=null){
fis.close();
}
如果(fos!=null){
fos.close();
}
}
}
私有静态密钥getKey(字符串机密)引发GeneralSecurityException{
KeyGenerator kgen=KeyGenerator.getInstance(类型);
init(128,新的SecureRandom(secret.getBytes());
SecretKey SecretKey=kgen.generateKey();
返回secretKey;
}
私有静态void crypt(InputStream in、OutputStream out、Cipher Cipher)抛出IOException、GeneralSecurityException{
int blockSize=cipher.getBlockSize()*1000;
int outputSize=cipher.getOutputSize(blockSize);
字节[]inBytes=新字节[块大小];
字节[]输出字节=新字节[outputSize];
int-inLength=0;
布尔更多=真;
而(更多){
inLength=英寸读取(以字节为单位);
if(inLength==块大小){
int outLength=cipher.update(inBytes,0,blockSize,outBytes);
out.write(outBytes,0,outLength);
}否则{
更多=错误;
}
}
如果(长度>0)
outBytes=cipher.doFinal(inBytes,0,inLength);
其他的
outBytes=cipher.doFinal();
out.write(输出字节);
}
公共字符串encryptString(String srcString,String keyString)引发GeneralSecurityException{
Key=getKey(键串);
Cipher Cipher=Cipher.getInstance(type+“/ECB/PKCS5Padding”);
cipher.init(cipher.ENCRYPT_模式,密钥);
byte[]coded=cipher.doFinal(srcString.getBytes());
返回byteArrayToHexString(编码);
}   
公共字符串解密字符串(字符串srcString,字符串keyString)引发GeneralSecurityException{
Key=getKey(键串);
Cipher Cipher=Cipher.getInstance(type+“/ECB/PKCS5Padding”);
cipher.init(cipher.DECRYPT_模式,密钥);
字节[]已解码=cipher.doFinal(hexStringToByteArray(srcString));
返回新字符串(已解码);
}
私有字符串byteArrayToHexString(字节[]原始)
{
如果(原始==null)
{
返回null;
}
最终StringBuilder十六进制=新StringBuilder(2*原始长度);
for(最终字节b:raw)
{
十六进制追加(十六进制字符((b&0xF0)>>4))
.append(十六进制字符((b&0x0F));
}
返回hex.toString();
}
公共静态字节[]hexStringToByteArray(字符串s){
如果(s==null | |(s.length()%2)==1)
{
抛出新的IllegalArgumentException();
}
最终字符[]字符=s.toCharArray();
最终整数长度=字符长度;
最终字节[]数据=新字节[len/2];

对于(int i=0;i不确定这是否是您的问题,但此块:

while (more) {
    inLength = in.read(inBytes);
    if (inLength == blockSize) {
        int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
        out.write(outBytes, 0, outLength);
    } else {
        more = false;
    }
}
至少在原则上是不正确的。in.read()理论上在到达文件结尾之前读取的块长度可能小于块长度。可能是操作系统的更新导致FileInputStream偶尔中断读取?在这种情况下,您将首先中断读取