Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
319 views
in Technique[技术] by (71.8m points)

java - When Decrypting Image, gives javax.crypto.BadPaddingException: pad block corrupted Android

Hi i'm new to android and Image encryption. My scenario is like this,

  • first I'm encrypting the image file.
  • Then I'm uploading it to the Server
  • From my app I'm downloading encrypted image and saving it in SD card.
  • then I'm decrypting it before set it to the imageView

(See bottom for all need methods I have used..)

But I'm getting javax.crypto.BadPaddingException: pad block corrupted when decrypting. I read some articles about this exception but all are about text encryption. Can you help me to avoid this. Thank you in advance

Image Encrption using ...

private byte[] encrypt(byte[] raw, byte[] clear) throws Exception
{
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(clear);
    return encrypted;
}

Here I'm saving several other images as well, all saved in sd card successfully...

for (int i = 0; i < imageUrls.size(); i++)
                {
                    File file = new File(imageUrls.get(i));

                    String metapath = CommonUtils.getDataFromPreferences("metaPath", "");
                    Log.d("metapath", metapath);
                    String extStorageDirectory = metapath + file.getName();

                    File wallpaperDirectory = new File(extStorageDirectory);
                    if (!wallpaperDirectory.exists() || wallpaperDirectory.length() == 0)
                    {
                        new DownloadImagesTask()
                            .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imageUrls.get(i));
                    }
                }
                Toast toast = Toast.makeText(ScratchDetailsActivity.this, "Lottery was purchased and saved to sdcard/E-Lottery",
                    Toast.LENGTH_LONG);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();

Image decryption...

decrypt the file here first argument is key and second is encrypted file which we get from SD card.

        decrpt = simpleCrypto.decrypt(KEY, getImageFileFromSdCard());
        bmpimg2 = BitmapFactory.decodeByteArray(decrpt, 0, decrpt.length);
        Drawable d = new BitmapDrawable(getResources(), bmpimg2);
        hiddenImage.setImageDrawable(d);

DownloadImageTask..

public class DownloadImagesTask extends AsyncTask<String, Void, InputStream>{
private String fileName;

@Override
protected InputStream doInBackground(String... urls)
{
    //Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    return download_Image(urls[0]);
}

@Override
protected void onPostExecute(InputStream result)
{
    storeImage(result);

}

private InputStream download_Image(String url)
{
    InputStream is = null;
    File file = new File(url);
    fileName = file.getName();
    try
    {
        URL aURL = new URL(url);
        URLConnection conn = aURL.openConnection();
        conn.connect();
        is = conn.getInputStream();
    }
    catch (OutOfMemoryError e)
    {
        Log.e("Hub", "Error getting the image from server : " + e.getMessage().toString());
    }
    catch (IOException e)
    {
        Log.e("Hub", "Error getting the image from server : " + e.getMessage().toString());
    }

    return is;
}

public void storeImage(InputStream is)
{

    String extStorageDirectory = CommonUtils.getDataFromPreferences("metaPath", "");

    Log.d("extStorageDirectory", extStorageDirectory);
    OutputStream outStream = null;

    File wallpaperDirectory = new File(extStorageDirectory);
    if (!wallpaperDirectory.exists())
    {
        wallpaperDirectory.mkdirs();
    }
    File outputFile = new File(wallpaperDirectory, fileName);
    if (!outputFile.exists() || outputFile.length() == 0)
    {
        try
        {
            outStream = new FileOutputStream(outputFile);
        }
        catch (FileNotFoundException e1)
        {
            e1.printStackTrace();
        }

        try
        {
            int bytesRead = -1;
            byte[] buffer = new byte[4096];
            while ((bytesRead = is.read(buffer)) != -1)
            {
                outStream.write(buffer, 0, bytesRead);
            }

            outStream.close();
            is.close();
            Log.d("ScratchActivtiy", "Image Saved");

        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();

        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}}

getImageFileFromSDCard method

/**
     * This method fetch encrypted file which is save in sd card and convert it in byte array after that this file will
     * be decrept.
     * 
     * @return byte array of encrypted data for decription.
     * @throws FileNotFoundException
     */

public byte[] getImageFileFromSdCard() throws FileNotFoundException
{

    byte[] inarry = null;

    try
    {
        String metapath = CommonUtils.getDataFromPreferences("metaPath", "");

        File imageFolder = new File(metapath);
        File urlFile = new File(selectedLottery.getImage());

        for (File f : imageFolder.listFiles())
        {
            if (urlFile.getName().equals(f.getName()))
                metapath = metapath + f.getName();
        }
        File imageFile = new File(metapath);
        //Convert file into array of bytes.
        FileInputStream fileInputStream = null;
        byte[] bFile = new byte[(int) imageFile.length()];
        fileInputStream = new FileInputStream(imageFile);
        fileInputStream.read(bFile);
        fileInputStream.close();
        inarry = bFile;

    }
    catch (IOException e)
    {
        Log.d("Exception", e.getMessage());
    }

    return inarry;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are a lot of things that might cause a Bad Padding exception. Obvious things to check are that for both encryption and decryption you are using:

  1. the same key, that is byte-for-byte the same.

  2. the same encryption mode (CBC, CTR or GCM usually).

  3. the same IV/Nonce, again byte-for-byte the same.

  4. the same padding (PKCS5 or PKCS7 are common).

Do not rely on system defaults, especially when encrypting on one system and decrypting on another, as you seem to be doing. If the system defaults are different, then your decryption will fail. Always explicitly set key, mode, IV and padding. There will be documented ways to do so in any reasonable crypto library.

If that doesn't solve it then you will need to do a bit more digging. Set the decryption method temporarily to NoPadding or whatever equivalent your library uses. That will let the decryption method ignore padding errors, and give you some output. Have a look at the output and compare it to the original input; you may have to look at hex dumps here to be sure what is happening.

Among the possibilities are:

  1. the output is complete garbage: your key is wrong, or the IV/Nonce is wrong for a stream cypher or GCM mode or CTR mode.

  2. the first block is garbage with the rest matching the plaintext: you have the wrong IV in CBC mode.

  3. the output matches with some extra stuff at the end: the extra stuff is padding. Set your decryption method to expect that type of padding.

If none of these happen, then ask again here, describing the symptoms.

When you have got a solution, you must set your decryption method back to expect the correct padding. Leaving it set to NoPadding is not secure since any old garbage can be added to the decrypted plaintext.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...