我需要下载mp3文件,必要时加密,解密临时mp3并听取。
作为参考,这个答案已在StackOverflow中完成
Encrypting files with AES on Android
所有步骤都有效。但是当我发送生成的MP3文件时,MediaPlayer无法识别并中断。
这些是我的下载和加密方法
public void executeAsyncDownload(String urlFile, String id, int position, HandlerCallback callback) {
String encryptedName = Cypher.md5(id);
if (MediaUtils.containsFile(encryptedName)) {
callback.onDownloadFinish(position);
return;
}
File dir = MediaUtils.getDestinationFolder(destination);
if (!dir.exists()) {
dir.mkdir();
}
try {
if (canceled)
return;
callback.onDownloadStart(position);
URL url = new URL(urlFile);
URLConnection connection = url.openConnection();
connection.connect();
int tamFile = connection.getContentLength();
String filePath = MediaUtils.getFilePath(MediaUtils.tempPath + encryptedName).toString();
InputStream fis = new BufferedInputStream(url.openStream());
OutputStream fos = new FileOutputStream(filePath);
File file = new File(filePath);
byte data[] = new byte[80192];
int count;
long total = 0;
while ((count = fis.read(data)) != -1) {
total += count;
if (tamFile > 0) {
int percentage = (int) (total * 100 / tamFile);
if (percentage % 20 == 0)
callback.onDownloadProgress(percentage, position);
}
fos.write(data, 0, count);
if (canceled) {
MediaUtils.deleteFile(file);
return;
}
}
if (canceled)
return;
byte[] key = (salt + cryptPassword).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 8);
SecretKeySpec sks = new SecretKeySpec(key, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, sks);
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
int b;
byte[] d = new byte[8192];
while ((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
OutputStream outputEncrypted = new FileOutputStream(dir + File.separator + encryptedName);
outputEncrypted.write(d);
outputEncrypted.close();
fos.flush();
fos.close();
fis.close();
MediaUtils.deleteFile(file);//delete temp file
callback.onDownloadFinish(position);
} catch (Exception e) {
e.printStackTrace();
callback.onDownloadError(position);
}
}
这是我的解密方法
@SafeVarargs
@Override
protected final File doInBackground(HashMap<String, Object>... params) {
String path = (String) params[0].get(FILE_PATH);
String fileName = String.valueOf(params[0].get(FILE_NAME));
boolean encrypted = (boolean) params[0].get(ENCRYPTED);
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + File.separator + path + File.separator);
File file;
if (!encrypted) {
file = new File(dir + File.separator + fileName);
return file;
}
file = new File(dir + File.separator + Cypher.md5(fileName));
File tempMp3 = null;
try {
tempMp3 = File.createTempFile(TEMP, MP3, context.getCacheDir());
tempMp3.deleteOnExit();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileInputStream fis = new FileInputStream(file);
byte[] key = (DownloadManager.salt + DownloadManager.cryptPassword).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 8);
SecretKeySpec sks = new SecretKeySpec(key, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
FileOutputStream fos = new FileOutputStream(tempMp3);
int b;
byte[] d = new byte[80192];
while ((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return tempMp3;
}
答案 0 :(得分:0)
您的加密或解密方法似乎都有拼写错误。
加密:
int b;
byte[] d = new byte[8192];
while ((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
在解密中:
int b;
byte[] d = new byte[80192];
while ((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
解密中的字节数组d比加密中的字节数组大10倍。
答案 1 :(得分:0)
这样做之后:
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
int b;
byte[] d = new byte[8192];
while ((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
OutputStream outputEncrypted = new FileOutputStream(dir + File.separator + encryptedName);
outputEncrypted.write(d);
outputEncrypted.close();
outputEncrypted
文件将只包含最后一个充满数据的缓冲区。此外,这些数据不会被加密。