1

Like many others over time I'm having issues with encryption in a system I'm maintaining.

Process A generates some encrypted text which later Process B must decode. They share the same code for this purpose which is as below:

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);
    }
}
}

The two processes run on separate servers, both Centos (5.3 for process A, 6.4 for Process B)

There are no apparent issues with Process A - The string to be encoded is done so reliably.

When process B starts, everything appears to be fine. It decodes and decrypts the required strings correctly.

At some point over the course of about 24 hours however, this stops working. At this point, I get the 'BadPaddingException "Given final block not properly padded"' Exceptions. This then continues every time the code is executed with any encoded string until such time as the process is restarted, at which point everything works again, including decoding strings that failed moments before.

At the time when this goes wrong, calling decrypt(encrypt("test")) will fail too so this seems to be unrelated to the actual encrypted value and more to do with the encryption and decryption getting out of sync some how.

If anyone could offer any suggestions about where I may be going wrong with this I'd appreciate it.

Many thanks in advance...

Andrew

  • 1
    1) Avoid sun.misc if possible. Java 8 has `util.Base64` classes as standard. 2) It might help to test decryption with `NoPadding` set so you can get a look at what is actually in the final block, which is presumably where the problem is. – rossum Mar 11 '15 at 16:34
  • 1
    Thanks Rossum - Sadly the encrypting system is stuck on Java 6. I'd also like to alter "PBEWithMD5AndDES" which is far from ideal. I'll see what I can see as suggested setting NoPadding. – user3514695 Mar 12 '15 at 08:39
  • 1
    In the end I've change to tripple des encryption in the hope that this will see the issue gone. I was unable to find anything wrong with the code as it was. – user3514695 Apr 02 '15 at 08:43

0 Answers0