Criptografia Bouncy and JCA

Boa tarde, galera estou com um problema com a criptografia bouncycastle vs JCA.

A situação é a seguinte:

Eu tenho que usar o BouncyCastle para criptografar dados AES no celular porque nem todos os celulares com suporte java tem o “java.security” então a implementação foi feita sem utilizar o provider do bouncy castle, só que o problema acontece quando a descriptografia é feita pelo JCA (utilizando qualquer provider e seja a criptografia feita em HSM ou na maquina mesmo), porque a ideia é apenas de cadastrar um novo provider e o código já funcionar sem precisar mudar nenhuma linha de código (essa é a ideia por trás do JCA), só que eu estou com serios problemas na hora de descriptografar com JCA algo que foi encriptografado por Bouncy castle, alguém aqui já passou por isso ? Lembrando que o contrario funciona, ou seja, se eu encriptar algo pelo JCA e descriptar pelo bouncy (utilizando aes) funciona perfeitamente.

Help, pois o prazo está chegando ao final.

Abaixo segue as duas classes e também a classe da JUnit que estou utilizando para testar.

AESCipherJCA

[code]public class AESCipherJCA {

private Cipher cipher;
private SecretKey secretKey;
//private IvParameterSpec iv;

public AESCipherJCA(byte[] aesKey) throws Exception {
	
	cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
	secretKey = new SecretKeySpec(aesKey, "AES");
	//iv = new IvParameterSpec(cipher.getIV());
}

public byte[] decrypt(byte[] plainText) throws Exception {

	cipher.init(Cipher.DECRYPT_MODE, secretKey);

	return cipher.doFinal(plainText);
}

public byte[] encrypt(byte[] plainText) throws Exception {

	cipher.init(Cipher.ENCRYPT_MODE, secretKey);

	return cipher.doFinal(plainText);
}

}[/code]

AESCipherBouncy

[code]public class AESCipherBouncy {

private ParametersWithIV aes_key;
private BlockCipher symmetricBlockCipher;
private int symmetricBlockSize;

public AESCipherBouncy(){};

public AESCipherBouncy(byte [] aesKey) throws IOException, InvalidCipherTextException {

	// Prepara o block symmetric de criptografia.
	symmetricBlockCipher = new CBCBlockCipher(new AESEngine());
	symmetricBlockSize = symmetricBlockCipher.getBlockSize();

	//org.bouncycastle.crypto.modes.
	
	// Inicializa a chave AES de criptografia.
	initAESKey(aesKey);
}

private void initAESKey(byte[] aesKey) {
	
	byte[] iv = new byte[symmetricBlockSize];
	aes_key = new ParametersWithIV(new KeyParameter(aesKey), iv);
}

public byte[] encrypt(byte[] message) throws DataLengthException, IllegalStateException, InvalidCipherTextException {
	
	symmetricBlockCipher.init(true, aes_key);
	
	int numBlocks = (message.length / symmetricBlockSize) + 1;
	byte[] plaintext = new byte[numBlocks * symmetricBlockSize];
	System.arraycopy(message, 0, plaintext, 0, message.length);
	byte[] ciphertext = new byte[numBlocks * symmetricBlockSize];

	for (int i = 0; i < ciphertext.length; i += symmetricBlockSize) {
		symmetricBlockCipher.processBlock(plaintext, i, ciphertext, i);
	}
	
	return ciphertext;
}

public byte[] decrypt(byte[] ciphertext) {
	
	symmetricBlockCipher.init(false, aes_key);
	byte[] plaintext = new byte[ciphertext.length];
	
	for (int i = 0; i < ciphertext.length; i += symmetricBlockSize) {
		symmetricBlockCipher.processBlock(ciphertext, i, plaintext, i);
	}

	return plaintext;
}

}[/code]

Test JUnit (Passa em todos menos no primeiro)

[code]public class AESCipherTest {

private String chaveAES = "?Pò%ܪ]ìV£gpÛ[";

@Test
public void testCriptyBouncyDecriptyJCA() throws Exception {
	
	String textoClaro = "Isso é um teste";
	
	AESCipher aesJCA = new AESCipherJCA(chaveAES.getBytes());
	AESCipher aesBouncy = new AESCipherBouncy(chaveAES.getBytes());
	
	byte [] textCrypt = aesBouncy.encrypt(textoClaro.getBytes());
	byte [] plainText = aesJCA.decrypt(textCrypt);
	
	assertEquals(textoClaro, new String(plainText).trim());
}

@Test
public void testCriptyJCADecriptyBouncy() throws Exception {
	
	String textoClaro = "Isso é um teste";
	
	AESCipher aesJCA = new AESCipherJCA(chaveAES.getBytes());
	AESCipher aesBouncy = new AESCipherBouncy(chaveAES.getBytes());
	
	byte [] textCrypt = aesJCA.encrypt(textoClaro.getBytes());
	byte [] plainText = aesBouncy.decrypt(textCrypt);
	
	assertEquals(textoClaro, new String(plainText).trim());
}

@Test
public void testCriptyBouncyDecriptyBouncy() throws Exception {
	
	String textoClaro = "Isso é um teste";
	
	AESCipher aesBouncy = new AESCipherBouncy(chaveAES.getBytes());
	
	byte [] textCrypt = aesBouncy.encrypt(textoClaro.getBytes());
	
	byte [] plainText = aesBouncy.decrypt(textCrypt);
	
	assertEquals(textoClaro, new String(plainText).trim());
}

@Test
public void testCriptyJCADecriptyJCA() throws Exception {
	
	String textoClaro = "Isso é um teste";
	
	AESCipher aesJCA = new AESCipherJCA(chaveAES.getBytes());
	
	byte [] textCrypt = aesJCA.encrypt(textoClaro.getBytes());
	byte [] plainText = aesJCA.decrypt(textCrypt);
	
	assertEquals(textoClaro, new String(plainText));
}

}[/code]

O erro é esse:

javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.SunJCE_h.b(DashoA12275) at com.sun.crypto.provider.SunJCE_h.b(DashoA12275) at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA12275) at javax.crypto.Cipher.doFinal(DashoA12275) at aes.AESCipherJCA.decrypt(AESCipherJCA.java:33) at AESCipherTest.testCriptyBouncyDecriptyJCA(AESCipherTest.java:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99) at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81) at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34) at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75) at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45) at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:71) at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35) at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42) at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34) at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)