0

I am stuck with a problem with AES Decryption in my android Application. I have searched a lot but unable to get the solution.

Here are the steps, what i am doing.

  • Encrypt the credit card number with my key send to the Web server.
  • Web server Decrypt the credit card number and save it.
  • When we fetch the credit card number from the Web service.
  • Then web server encrypt the credit card number with the same key and send to Us.
  • Now When we decrypt this number, it throws bad padding exception for some credit card number information.

Also encrypted information is not same coming from the server, what we have send in encrypted format. While the same thing is done in iPhone app, and iPhone is able to decrypt the information successfully.

I am using the following code for encryption and decryption.

public class AES256Cipher {

    public static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

    public static String AES_Encode(String str, String key) throws java.io.UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

        byte[] textBytes = str.getBytes("UTF-8");
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
             SecretKeySpec newKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
             Cipher cipher = null;
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);

        return Base64.encodeToString(cipher.doFinal(textBytes), 0);
    }

    public static String AES_Decode(String str, String key) throws java.io.UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

        byte[] textBytes =Base64.decode(str,0);
        //byte[] textBytes = str.getBytes("UTF-8");
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        SecretKeySpec newKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
        return new String(cipher.doFinal(textBytes), "UTF-8");
    }

Please suggest.

EDIT: I one more thing, it is working for < 16 digits information. When we put the 16 digit information, then it is throwing the Exception in decryption.

Himanshu
  • 1,066
  • 6
  • 19
  • 44
  • Please show the code of the server side as well. – Codo Dec 27 '12 at 12:27
  • 5
    I don't know why your error occurs, but your code is bad from a crypto point of view. 1) No IV 2) No MAC 3) Uses text as key directly 4) This code doesn't address key management at all, which is the actual hard problem. | Have you considered simply using TLS instead of building the crypto protocol yourself? | Since you're dealing with credit cards, you need to look into PCI compliance. – CodesInChaos Dec 27 '12 at 12:29
  • How long is your key (in bytes)? And where is the initialization vector coming from? How is it shared with the server side? – Codo Dec 27 '12 at 12:31
  • Thanks for your prompt responses, My key length is of 256 bytes, And it is shared in JSON request to the web server. – Himanshu Dec 27 '12 at 12:56
  • @CodesInChaos I have use IV bytes as mentioned above IVBytes. Also i have tried with the new IvParameterSpec(new byte[cipher.getBlockSize()]); – Himanshu Dec 27 '12 at 12:58
  • 1
    Your code shows a constant you call IV. But since an IV should be different for each encryption, that's no real IV. | "My key length is of 256 bytes" AES doesn't support 256 byte keys. | "it is shared in JSON request to the web server" what about an attacker intercepting that JSON request? He'll get the key, and then he'll decrypt the credit card number. – CodesInChaos Dec 27 '12 at 13:01
  • It's very unlikely that the key is 256 bytes long if you `getBytes("UTF-8")` to generate the byte array. Unless you're using all ASCII characters, the final length is difficult to predict. – Codo Dec 27 '12 at 14:11

1 Answers1

3

If the server encounters unknown encodings that don't map to specific characters then the key will not transfer properly and fail once in a while, resulting in an incorrect key. The ciphertext is encoded using base64 so that's probably OK, but your key may not be so lucky.

Note that any change in the key or the last blocks of the ciphertext is likely to result in a BadPaddingException.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • 2
    This is very likely the answer to your question, but you should take the advice of Codes *very* seriously. I would advise hiring an expert as you are very likely be liable for damages if anything goes wrong. – Maarten Bodewes Dec 27 '12 at 14:12
  • 1
    For some more advice, see [here](http://stackoverflow.com/questions/4551263/how-can-i-convert-string-to-secretkey/8828196#8828196). Note that this does not solve your key management issues. – Maarten Bodewes Dec 27 '12 at 14:15
  • Thank you! almost a month trying to figure why was it! – pkarc Jan 16 '18 at 21:39