Question

Am I doing it right or is there a mistake? The test program I'm still trying to implement is running without any exceptions or errors. But it's not doing the thing it has to do and I can't find the problem.

Here is the Android code that attempts to decrypt:

private static final int IO_BUFFER_SIZE = 4 * 1024;
@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

            try {
                AssetManager am = this.getAssets();
                InputStream is = am.open("2000_1.jpg_encrypted"); // get the encrypted image from assets folder

                ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                byte[] b = new byte[IO_BUFFER_SIZE];  
                int read;  
                while ((read = is.read(b)) != -1) {  //convert inputstream to bytearrayoutputstream
                    baos.write(b, 0, read);
                }                           
                //START
                long start = System.currentTimeMillis()/1000L; // start

                //byte[] keyStart = "MARTIN_123_MARTIN_123".getBytes();  // specific key value 
                KeyGenerator kgen = KeyGenerator.getInstance("AES/CBC/PKCS5Padding");   //aes
                SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
                //sr.setSeed(keyStart);
                kgen.init(128, sr); 
                //SecretKey skey = kgen.generateKey();
                //byte[] key = skey.getEncoded();    

                byte[] key = "MARTIN_123_MARTIN_123".getBytes("UTF-8");
                byte[] iv = "1234567890123456".getBytes("UTF-8");
                byte[] decryptedData = decrypt(key, iv, b);


                //END
                long end = System.currentTimeMillis()/1000L;    // end
                Log.d("TEST","Time start "+ String.valueOf(start)); //showing the strat in ms
                Log.d("TEST","Time end "+ String.valueOf(end));     //showing the end in ms

                Bitmap bitmap = BitmapFactory.decodeByteArray(decryptedData , 0, decryptedData .length);    //decoding bytearrayoutputstream to bitmap
                //String filepath = Environment.getExternalStorageDirectory()+"bitmap";
                FileOutputStream fos = new FileOutputStream("sdcard/DCIM/100ANDRO");
                fos.write(decryptedData);
                fos.close();

                is.close(); // close the inputstream
                baos.close(); // close the bytearrayoutputstream
            }
            catch(Exception e){
                e.fillInStackTrace();
            }
        } 

        //decrypt
        private byte[] decrypt(byte[] raw, byte[] iv, byte[] encrypted) throws Exception {
      SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      IvParameterSpec ivspec = new IvParameterSpec(iv);         
      cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivspec);
      byte[] decrypted = cipher.doFinal(encrypted);

      return decrypted;
    }

Here is the PHP code that encrypts:

$folder = $this->getConfiguration()->getAppRootDir() . '/temp_encryption_testing/';

$files = array(
        '007FRAMESUPERIOR.jpg',
        '2000_1.jpg',
        'APLICACIONdescargaliga.jpg',
        'APPCOMMENTS.pdf',
        'AUDIOVISUALFOTO02.jpg'
        );
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $key = "MARTIN_123_MARTIN_123";
foreach($files as $file)
{
            $input_file = $folder . $file;
$text = file_get_contents($input_file);
            //$text = "Meet me at 11 o'clock behind the monument.";
            echo strlen($text) . "\n";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
            echo strlen($crypttext) . "\n";
            file_put_contents($input_file . '_encrypted', $crypttext);
        }

Any help will be appreciated :)

Was it helpful?

Solution

You are trying to decrypt with a randomly generated key (adding a seed to a SecureRandom only supplements the random state). That is sure to fail.

If "MARTIN_123_MARTIN_123".getBytes() is your key (or rather: the first 16 bytes of it), you should just pass that directly to your decrypt-method:

byte[] decryptedData = decrypt(keyStart,b);

Okay, from your comment, I can see that you are encrypting with PHP:mcrypt using AES-256/ECB/ZeroBytePadding (zero-byte padding is implicit with mcrypt).

First of all: ECB is not a safe mode - especially for images (though JPGs are probably not quite as bad as BMPs). If you decide to change to CBC, remember that you need to transmit the IV, f.x. by prepending it to the encrypted data. But if you want to decrypt CBC, you need to indicate it in your Cipher.getInstance()-call (you currently use AES/CBC/PKCS5Padding).

Zero-byte-padding is not really removable unless you know the length of the data. So you must either transmit the length or add PKCS#7 padding before encrypting the data.

Finally: you encrypt using AES-256. That uses a 32-byte key. According to the mcrypt-documentation it adds \0s if the key is too short, so you will either have to use an actual 32-byte key or add \0s to the Android-side, too.

Change your code to this on the Android side:

byte[] key = "MARTIN_123456789".getBytes("UTF-8");
byte[] iv = "1234567890123456".getBytes("UTF-8");
byte[] decryptedData = decrypt(key, iv, b);

private byte[] decrypt(byte[] raw, byte[] iv, byte[] encrypted) throws Exception {
  SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  IvParameterSpec ivspec = new IvParameterSpec(iv);         
  cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivspec);
  byte[] decrypted = cipher.doFinal(encrypted);

  return decrypted;
}

And on the PHP side:

function addpadding($string, $blocksize = 16){
    $len = strlen($string);
    $pad = $blocksize - ($len % $blocksize);
    $string .= str_repeat(chr($pad), $pad);
    return $string;
}

$key = "MARTIN_123456789";
$iv = "1234567890123456"
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, addpadding($text), MCRYPT_MODE_CBC, $iv);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top