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偶尔中断读取?在这种情况下,您将首先中断读取