Java BadPaddingException几个小时后“给定的最后一个块未正确填充”

Java BadPaddingException几个小时后“给定的最后一个块未正确填充”,java,encryption,badpaddingexception,Java,Encryption,Badpaddingexception,和许多其他人一样,随着时间的推移,我在维护的系统中遇到了加密问题 进程A生成一些加密文本,稍后进程B必须对其进行解码。它们为此目的共享相同的代码,如下所示: public class DesEncryption { private Cipher mEcipher; private Cipher mDcipher; private byte[] salt = { (byte) 0x08, (byte) 0x90, (byte) 0xA6, (byte) 0x4B,

和许多其他人一样,随着时间的推移,我在维护的系统中遇到了加密问题

进程A生成一些加密文本,稍后进程B必须对其进行解码。它们为此目的共享相同的代码,如下所示:

public class DesEncryption {
private Cipher mEcipher;
private Cipher mDcipher;

private byte[] salt = {
        (byte) 0x08, (byte) 0x90, (byte) 0xA6, (byte) 0x4B,
        (byte) 0xBB, (byte) 0x51, (byte) 0x3C, (byte) 0xDE
};

// Iteration count
int iterationCount = 19;

DesEncryption(String passPhrase) throws EncryptionException {
    try {
        // Create the key
        KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
        SecretKey key = SecretKeyFactory.getInstance(
                "PBEWithMD5AndDES").generateSecret(keySpec);
        mEcipher = Cipher.getInstance(key.getAlgorithm());
        mDcipher = Cipher.getInstance(key.getAlgorithm());

        // Prepare the parameter to the ciphers
        AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

        // Create the ciphers
        mEcipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
        mDcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
    } catch (java.security.InvalidAlgorithmParameterException e) {
        throw new EncryptionException(e);
    } catch (java.security.spec.InvalidKeySpecException e) {
        throw new EncryptionException(e);
    } catch (javax.crypto.NoSuchPaddingException e) {
        throw new EncryptionException(e);
    } catch (java.security.NoSuchAlgorithmException e) {
        throw new EncryptionException(e);
    } catch (java.security.InvalidKeyException e) {
        throw new EncryptionException(e);
    }
}

public String encrypt(String str) throws EncryptionException {
    try {
        // Encode the string into bytes using utf-8
        byte[] utf8 = str.getBytes("UTF8");

        // Encrypt
        byte[] enc = mEcipher.doFinal(utf8);

        // Encode bytes to base64 to get a string
        return new sun.misc.BASE64Encoder().encode(enc);
    } catch (javax.crypto.BadPaddingException e) {
        throw new EncryptionException(e);
    } catch (IllegalBlockSizeException e) {
        throw new EncryptionException(e);
    } catch (UnsupportedEncodingException e) {
        throw new EncryptionException(e);
    } catch (java.io.IOException e) {
        throw new EncryptionException(e);
    }
}

public String decrypt(String str) throws EncryptionException {
    try {
        // Decode base64 to get bytes
        byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);

        // Decrypt
        byte[] utf8 = mDcipher.doFinal(dec);

        // Decode using utf-8
        return new String(utf8, "UTF8");
    } catch (javax.crypto.BadPaddingException e) {
        throw new EncryptionException(e);
    } catch (IllegalBlockSizeException e) {
        throw new EncryptionException(e);
    } catch (UnsupportedEncodingException e) {
        throw new EncryptionException(e);
    } catch (java.io.IOException e) {
        throw new EncryptionException(e);
    }
}
}
这两个进程在不同的服务器上运行,Centos 5.3用于进程A,6.4用于进程B

进程A没有明显的问题-要编码的字符串是如此可靠

当进程B开始时,一切似乎都很好。它正确地解码和解密所需的字符串

然而,在大约24小时的某个时间点上,这会停止工作。在这一点上,我得到了“BadPaddingException-Given final block not Rightly padded”异常。然后,每次使用任何编码字符串执行代码时,此过程都会继续,直到进程重新启动,此时所有操作都会再次工作,包括解码之前失败的字符串

当出现错误时,调用decryptencrypttest也会失败,因此这似乎与实际的加密值无关,更多的是与加密和解密不同步有关

如果有人能对我在这方面可能出现的问题提出任何建议,我将不胜感激

非常感谢


Andrew

1尽可能避免使用sun.misc。Java 8的标准类是util.Base64。2使用NoPadding set测试解密可能会有所帮助,这样您就可以查看最后一个块中的实际内容,这大概就是问题所在。感谢Rossum-遗憾的是,加密系统在Java 6上卡住了。我还想改变PBewithmd5和des,这远远不是理想的。我会看看我能看到的建议设置。最后我改为tripple des encryption,希望这能解决这个问题。我找不到代码的任何错误。