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
658 views
in Technique[技术] by (71.8m points)

how to encrypt and decrypt audio file android

I am trying to encrypt and then decrypt audio file . Everything goes right but when I try to decrypt the encrypted audio , everytime I got this exception

javax.crypto.BadPaddingException: pad block corrupted

My MainActivity is like this: I want to decrypt and play the song side by side

public class MainActivity extends Activity{

private final String KEY = "abc";
Button btn_Dec, btn_In;
byte[] incrept;
byte[] decrpt;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ctx = this;
    btn_Dec = (Button) findViewById(R.id.button2);
    btn_In = (Button) findViewById(R.id.button1);
    btn_Dec.setOnClickListener(btnDecListner);
    btn_In.setOnClickListener(btnInListner);

}

public OnClickListener btnDecListner = new OnClickListener() {
    public void onClick(View v) {
        VincentFileCrypto simpleCrypto = new VincentFileCrypto();
        try {
            // decrypt the file here first argument is key and second is encrypted file which we get from SD card.
            decrpt = simpleCrypto.decrypt(KEY, getAudioFileFromSdCard());
            //play decrypted audio file.
            playMp3(decrpt);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

};
Context ctx;
public OnClickListener btnInListner = new OnClickListener() {
    public void onClick(View v) {
        VincentFileCrypto simpleCrypto = new VincentFileCrypto();
        try {
            // encrypt audio file send as second argument and corresponding key in first argument.
            incrept = simpleCrypto.encrypt(KEY, getAudioFile());
            //Store encrypted file in SD card of your mobile with name vincent.mp3.
            FileOutputStream fos = new FileOutputStream(new File("/sdcard/vincent.mp3"));
            fos.write(incrept);
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();

        }

    }

};


/**
 * @return byte array for encryption.
 * @throws FileNotFoundException
 */


public byte[] getAudioFile() throws FileNotFoundException

{

    byte[] audio_data = null;

    byte[] inarry = null;


    AssetManager am = ctx.getAssets();

    try {

        InputStream is = am.open("Sleep Away.mp3"); // use recorded file instead of getting file from assets folder.

        int length = is.available();

        audio_data = new byte[length];


        int bytesRead;

        ByteArrayOutputStream output = new ByteArrayOutputStream();

        while ((bytesRead = is.read(audio_data)) != -1)

        {

            output.write(audio_data, 0, bytesRead);

        }

        inarry = output.toByteArray();


    } catch (IOException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    }


    return inarry;

}


/**
 * 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[] getAudioFileFromSdCard() throws FileNotFoundException
{
    byte[] inarry = null;
    try {
        //getting root path where encrypted file is stored.
        File sdcard = Environment.getExternalStorageDirectory();
        File file = new File(sdcard, "vincent.mp3"); //Creating file object
        //Convert file into array of bytes.
        FileInputStream fileInputStream = null;
        byte[] bFile = new byte[(int) file.length()];
        fileInputStream = new FileInputStream(file);
        fileInputStream.read(bFile);
        fileInputStream.close();
        inarry = bFile;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return inarry;

}


/**
 * This Method is used to play audio file after decrepting.
 *
 * @param mp3SoundByteArray : This is our audio file which will be play and it converted in byte array.
 */

private void playMp3(byte[] mp3SoundByteArray) {

    try {
        // create temp file that will hold byte array
        File tempMp3 = File.createTempFile("kurchina", "mp3", getCacheDir());
        tempMp3.deleteOnExit();
        FileOutputStream fos = new FileOutputStream(tempMp3);
        fos.write(mp3SoundByteArray);
        fos.close();
        // Tried reusing instance of media player
        // but that resulted in system crashes...
        MediaPlayer mediaPlayer = new MediaPlayer();
        FileInputStream fis = new FileInputStream(tempMp3);
        mediaPlayer.setDataSource(fis.getFD());
        mediaPlayer.prepareAsync();
        mediaPlayer.start();
    } catch (IOException ex) {
        ex.printStackTrace();

    }

}

}

The encryption and decryption methods are mentioned in this class

public class VincentFileCrypto {

public  byte[] encrypt(String seed, byte[] cleartext) throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] result = encrypt(rawKey, cleartext);
    //  return toHex(result);
    return result;
}

public  byte[] decrypt(String seed, byte[] encrypted) throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] enc = encrypted;
    byte[] result = decrypt(rawKey, enc);
    return result;
}

//done
private  byte[] getRawKey(byte[] seed) throws Exception {
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    sr.setSeed(seed);
    kgen.init(128, sr); // 192 and 256 bits may not be available
    SecretKey skey = kgen.generateKey();
    byte[] raw = skey.getEncoded();
    return raw;
}

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;
}

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

}
See Question&Answers more detail:os

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

1 Answer

0 votes
by (71.8m points)

After days of research and hard work I found the solution ,may help and save somebody's else time . Here is my answer. I changed the above code logic like this

now what is happening , I am able to successfully encrypt the file and save it in the sdcard and then decrypt it to play . No body else can play the audio.

here we go : happy coding

public class Main2Activity extends AppCompatActivity {

    private String encryptedFileName = "encrypted_Audio.mp3";
    private static String algorithm = "AES";
    static SecretKey yourKey = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        //saveFile("Hello From CoderzHeaven asaksjalksjals");
        try {
            saveFile(getAudioFile());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        decodeFile();

    }

    public static SecretKey generateKey(char[] passphraseOrPin, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
        // Number of PBKDF2 hardening rounds to use. Larger values increase
        // computation time. You should select a value that causes computation
        // to take >100ms.
        final int iterations = 1000;

        // Generate a 256-bit key
        final int outputKeyLength = 256;

        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations, outputKeyLength);
        SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
        return secretKey;
    }

    public static SecretKey generateKey() throws NoSuchAlgorithmException {
        // Generate a 256-bit key
        final int outputKeyLength = 256;
        SecureRandom secureRandom = new SecureRandom();
        // Do *not* seed secureRandom! Automatically seeded from system entropy.
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(outputKeyLength, secureRandom);
        yourKey = keyGenerator.generateKey();
        return yourKey;
    }

    public static byte[] encodeFile(SecretKey yourKey, byte[] fileData)
            throws Exception {
        byte[] encrypted = null;
        byte[] data = yourKey.getEncoded();
        SecretKeySpec skeySpec = new SecretKeySpec(data, 0, data.length, algorithm);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(
                new byte[cipher.getBlockSize()]));
        encrypted = cipher.doFinal(fileData);
        return encrypted;
    }

    public static byte[] decodeFile(SecretKey yourKey, byte[] fileData)
            throws Exception {
        byte[] decrypted = null;
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, yourKey, new IvParameterSpec(new byte[cipher.getBlockSize()]));
        decrypted = cipher.doFinal(fileData);
        return decrypted;
    }

    void saveFile(byte[] stringToSave) {
        try {
            File file = new File(Environment.getExternalStorageDirectory() + File.separator, encryptedFileName);

            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            yourKey = generateKey();
            byte[] filesBytes = encodeFile(yourKey, stringToSave);
            bos.write(filesBytes);
            bos.flush();
            bos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void decodeFile() {

        try {
            byte[] decodedData = decodeFile(yourKey, readFile());
           // String str = new String(decodedData);
            //System.out.println("DECODED FILE CONTENTS : " + str);
            playMp3(decodedData);

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

    public byte[] readFile() {
        byte[] contents = null;

        File file = new File(Environment.getExternalStorageDirectory()
                + File.separator, encryptedFileName);
        int size = (int) file.length();
        contents = new byte[size];
        try {
            BufferedInputStream buf = new BufferedInputStream(
                    new FileInputStream(file));
            try {
                buf.read(contents);
                buf.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return contents;
    }

    public byte[] getAudioFile() throws FileNotFoundException
    {
        byte[] audio_data = null;
        byte[] inarry = null;
        AssetManager am = getAssets();
        try {
            InputStream is = am.open("Sleep Away.mp3"); // use recorded file instead of getting file from assets folder.
            int length = is.available();
            audio_data = new byte[length];
            int bytesRead;
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            while ((bytesRead = is.read(audio_data)) != -1) {
                output.write(audio_data, 0, bytesRead);
            }
            inarry = output.toByteArray();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return inarry;

    }

    private void playMp3(byte[] mp3SoundByteArray) {

        try {
            // create temp file that will hold byte array
            File tempMp3 = File.createTempFile("kurchina", "mp3", getCacheDir());
            tempMp3.deleteOnExit();
            FileOutputStream fos = new FileOutputStream(tempMp3);
            fos.write(mp3SoundByteArray);
            fos.close();
            // Tried reusing instance of media player
            // but that resulted in system crashes...
            MediaPlayer mediaPlayer = new MediaPlayer();
            FileInputStream fis = new FileInputStream(tempMp3);
            mediaPlayer.setDataSource(fis.getFD());
            mediaPlayer.prepare();
            mediaPlayer.start();
        } catch (IOException ex) {
            ex.printStackTrace();

        }

    }
}

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

...