Java AES CTR-如何附加到CipherOutputStream?

Java AES CTR-如何附加到CipherOutputStream?,java,android,encryption,cryptography,aes,Java,Android,Encryption,Cryptography,Aes,我正在使用AES/CTR/NOPANDING对应用程序中下载的文件进行加密。加密与下载一起完成。当互联网在下载过程中不可用时,我需要暂停下载并在网络可用时恢复它。我使用FileOutputStream(mFile,true)将其余数据附加到文件中。问题是我不知道如何正确地附加到CipherOutputStream。当前实现创建垃圾数据 这是我的加密方法 private void downloadAndEncrypt() throws Exception { URL url = new

我正在使用AES/CTR/NOPANDING对应用程序中下载的文件进行加密。加密与下载一起完成。当互联网在下载过程中不可用时,我需要暂停下载并在网络可用时恢复它。我使用FileOutputStream(mFile,true)将其余数据附加到文件中。问题是我不知道如何正确地附加到CipherOutputStream。当前实现创建垃圾数据

这是我的加密方法

private void downloadAndEncrypt() throws Exception {

    URL url = new URL(mUrl);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

    long downloaded = 0;

    if(mFile.exists()){
        Logger.e("File exists. Resume Download");
        downloaded = mFile.length();
        connection.setRequestProperty("Range", "bytes=" + (int)downloaded + "-");
    }else{
        Logger.e("File doesn't exists. Start Download");
    }
    connection.connect();

    int lenghtOfFile = connection.getContentLength();

    if (connection.getResponseCode() != HttpURLConnection.HTTP_OK && connection.getResponseCode() != HttpURLConnection.HTTP_PARTIAL) {
        throw new IOException("server error: " + connection.getResponseCode() + ", " + connection.getResponseMessage());
    }

    BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());
    FileOutputStream fileOutputStream;
    if (downloaded == 0)
        fileOutputStream = new FileOutputStream(mFile);
    else
        fileOutputStream = new FileOutputStream(mFile, true);

    CipherOutputStream cipherOutputStream = new CipherOutputStream(fileOutputStream, mCipher);

    byte buffer[] = new byte[1024 * 1024];
    int bytesRead;
    long total = 0;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        total += bytesRead;
        publishProgress((int) ((total * 100) / lenghtOfFile));
        cipherOutputStream.write(buffer, 0, bytesRead);
    }

    inputStream.close();
    cipherOutputStream.close();
    connection.disconnect();
}

密文应该看起来像垃圾,因为它是伪随机的(当然,除非你知道密钥,否则它看起来像随机数据)。如果下载完成而没有任何中断,一切正常。我可以通过解密来访问该文件。当我继续下载(附加到文件)时,问题就出现了。好吧,那么当暂停/继续下载以及介于两者之间的任何内容时,
mCipher会发生什么呢?密码是从应用程序本身中存储的密钥和iv生成的。因此,cipher不会有任何更改。CTR模式使用计数器。当您重新初始化密码时,Java当然会将计数器重置为IV值。因此,您需要通过除以加密的块数来重新计算IV,然后“加密”几个字节到精确的偏移量。或者使用CTR模式实现,当然,您可以在其中明确指示偏移量。