我正在尝试加密然后解密音频文件。一切顺利,但当我尝试解密加密音频时,每次我都遇到此异常
javax.crypto.BadPaddingException:pad block corrupted
我的主要活动是这样的:我想要解密并一起播放这首歌
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();
}
}
}
本课程中提到了加密和解密方法
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;
}
}
答案 0 :(得分:22)
经过数天的研究和努力,我找到了解决方案,可能会帮助并节省别人的时间。这是我的答案。我像这样改变了上面的代码逻辑
现在发生了什么,我能够成功加密文件并将其保存在SD卡中,然后解密它以进行播放。没有其他人可以播放音频。
我们走了:快乐编码
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();
}
}
}