4

I have the following PHP routine to encrypt my communication with the client:

public static function encrypt($input, $key) {
        $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); 
        $input = AES::pkcs5_pad($input, $size); 
        $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, ''); 
        $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); 
        mcrypt_generic_init($td, $key, $iv); 
        $data = mcrypt_generic($td, $input); 
        mcrypt_generic_deinit($td); 
        mcrypt_module_close($td); 
        $data = base64_encode($data); 
        return $data; 
} 

and the following Java rotuine to decrypt my communication with the server:

public static String decrypt(String input, String key) {
        byte[] output = null;
        try {
            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skey);
            output = cipher.doFinal(Base64.decode(input,Base64.NO_WRAP));
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return new String(output);
}

Why does the following decryption routine throws an exception?

java.lang.IllegalArgumentException: bad base-64

Edit: After hardcoding the string into the code I am getting a BadPaddingException.

my input to decrypt function :

wrmRa2hAoseNOev6/ascapxkLQRGX/GW3DQm3ETwBH7gJm1NetkgGFzgY4kZTE10Tv45YIcy/xoodq/GumSY5hsao1s4bkuKXZeim/IDTVr3elrqX13b81/XE5iB3iJrAqny2dQ5SsWso0lUcAZGS2Wls/lTeQiIKXEaOh7iZZ3xOtM6633iNcoiFxEnX5A0dMrdRNEOkmQ3UnQmuIGTSv0RLKuPv5r5dplGZ3N2LMMpoB0AMu3DSXFEdiD4XN49
NotGI
  • 458
  • 9
  • 21
  • http://stackoverflow.com/questions/23241257/bad-base-64-error – USKMobility Oct 01 '16 at 10:07
  • @USKMobility, tried using URL_SAFE alone and it didn't work, trying the answer that was suggested now. – NotGI Oct 01 '16 at 10:28
  • try to observe your input string that have non-base64 character – USKMobility Oct 01 '16 at 10:30
  • @USKMobility my input string is directly from the PHP function, is it possible it will generate non Base64 chars? – NotGI Oct 01 '16 at 10:31
  • It is best not to use mcrypt, it is abandonware, has not been updated in years and does not support standard PKCS#7 (née PKCS#5) padding, only non-standard null padding that can't even be used with binary data. mcrypt had many outstanding [bugs](https://sourceforge.net/p/mcrypt/bugs/) dating back to 2003. Instead consider using [defuse](https://github.com/defuse/php-encryption) or [RNCryptor](https://github.com/RNCryptor), they provide a complete solution and are being maintained and is correct. – zaph Oct 01 '16 at 11:10
  • @zaph, so you think the problem is in the PHP code rather than in the Java code? – NotGI Oct 01 '16 at 11:12
  • There is nothing wrong with the Base64 string in your question, it is 256 character ong and has no invalid characters, new lines, etc. and decoded to 192 bytes. – zaph Oct 01 '16 at 11:18
  • By putting the decode in an argument you make debugging more difficult, seperate actions and you make things clearer and easier to find errors. As it is tou can't see the decoded Base64 and the error occurs on the same line as the decrpt so the compiler can not properly supply the correct line. – zaph Oct 01 '16 at 11:23
  • @zaph Something is strange however as I get `uudecode: stdin: /dev/stdout: character out of range: [33-96]` on the raw string. – Tigger Oct 01 '16 at 11:23
  • What was the input to the encrypt method, key and data? PHP used non-standard padding so if the input length was not an edxact multiple of the block size pas=dding will be added. Also ECB mode is very insecure, you should use CBC mode with a random IV. Create a block size random IV (16-bytes for AES), prefix the encrypted data with it and use it. On decryption seperate the IV from the data and use the IV. – zaph Oct 01 '16 at 11:27
  • @zaph, the data is encrypted before the AES so I don't worry about ECB being insecure. But how can I fix php's padding or let the decryption know that i'm using non standart padding? – NotGI Oct 01 '16 at 13:52
  • @zaph just to make sure, but do you think if i switch my method to CBC it will work? – NotGI Oct 01 '16 at 15:11
  • 1. Chaging to CBC will not solve the problem you have here but will provide a secure solution. 2. Why are you encrypting already encrypted data? 3. You need to provide data in, data out and key (with the encrypted data in hex) for both encryption and decryption. – zaph Oct 01 '16 at 15:29

1 Answers1

1

It is possible that you need to use:

Base64.decode(input,Base64.NO_WRAP|Base64.URL_SAFE)

It is also possible you need a different combo of flags too.

It also depends how you are getting the base64 string. Sometimes the '+' is converted to a ' ' (space) if it transferred from a URL or other online source.

Tigger
  • 8,980
  • 5
  • 36
  • 40
  • I still get bad-base64, the string I'm encrypting on the php script is constant it's a string containing javascript that doesn't change. – NotGI Oct 01 '16 at 10:29
  • Without seeing the base64 string or knowing exactly how you are transferring the base64 string I can only guess. I'm guessing this might not be something you want to share, but maybe you can do a test case that also produces the error and you can share. – Tigger Oct 01 '16 at 10:35
  • I get the usual base64 string with no bad chars, it doesn't make sense. – NotGI Oct 01 '16 at 10:38
  • It makes sense to me - it all depends on the transfer method. Just for fun / debug, you could do a test by hard-coding the base64 string in to your Java to see if that works. The [Wikipedia article](https://en.wikipedia.org/wiki/Base64) might help too. – Tigger Oct 01 '16 at 10:43
  • I hardcoded as you suggested and now I'm getting a BadPaddingException, also added the base64 string to thread and using your Base64.NO_WRAP | Base64.URL_SAFE causes a bad-base64 exception, any ideas? – NotGI Oct 01 '16 at 10:54
  • I think that base64 string is not valid unless the unencoded data is binary. The length and characters are valid btw, but I think the unencoded data is meant to be a string. – Tigger Oct 01 '16 at 11:19