I have the following code.
byte[] input = etInput.getText().toString().getBytes();
byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
// encryption pass
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
String strLength = new String(cipherText,"US-ASCII");
byte[] byteCiphterText = strLength.getBytes("US-ASCII");
Log.e("Decrypt", Integer.toString(byteCiphterText.length));
etOutput.setText(new String(cipherText,"US-ASCII"));
cipherText = etOutput.getText().toString().getBytes("US-ASCII");
Log.e("Decrypt", Integer.toString(cipherText.length));
ptLength += cipher.doFinal(plainText, ptLength);
Log.e("Decrypt", new String(plainText));
Log.e("Decrypt", Integer.toString(ptLength));
It works perfectly. But once I convert it to the class. It always hit the error in this line.
ptLength += cipher.doFinal(plainText, ptLength);
Error:Pad block corrupted
I have checked and both code are exactly the same. Even the value passed in conversion string to byte all is no different from the code above. Any idea what's wrong with the code?
public String Encrypt(String strPlainText) throws Exception, NoSuchProviderException,
NoSuchPaddingException {
byte[] input = strPlainText.getBytes();
byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
// encryption pass
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
return new String(cipherText, "US-ASCII");
}
public String Decrypt(String strCipherText) throws Exception,
NoSuchProviderException, NoSuchPaddingException {
byte[] cipherText = strCipherText.getBytes("US-ASCII");
int ctLength = cipherText.length;
byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
// decryption pass
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
ptLength += cipher.doFinal(plainText, ptLength);
return new String(plainText);
}
As Yann Ramin said, using String is a failure for cipher in/output. This is binary data that
Use plain byte[] as in your first example or go for hex encoding or base64 encoding the byte[].
// this is a quick example - dont use sun.misc inproduction
// - go for some open source implementation
String encryptedString = new sun.misc.BASE64Encoder.encodeBuffer(encryptedBytes);
This string can be safely transported and mapped back to bytes.
EDIT
Perhaps safest way to deal with the length issue is to always use streaming implementation (IMHO):
Example
static public byte[] decrypt(Cipher cipher, SecretKey key, byte[]... bytes)
throws GeneralSecurityException, IOException {
cipher.init(Cipher.DECRYPT_MODE, key);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int i = 0; i < bytes.length; i++) {
bos.write(cipher.update(bytes[i]));
}
bos.write(cipher.doFinal());
return bos.toByteArray();
}
You have specified PKCS7 Padding. Is your padding preserved when stored in your String object? Is your string object a 1:1 match with the bytes output by the cipher? In general, String is inappropriate for passing binary data, such as a cipher output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With