加密和解密文件

时间:2016-01-20 17:08:51

标签: java android encryption cryptography

我需要下载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;
}

2 个答案:

答案 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文件将只包含最后一个充满数据的缓冲区。此外,这些数据不会被加密。