java - 如何加密和解密大视频文件

标签 java android

我想将视频文件存储在只能我的应用程序访问的存储器中。外部用户不应该能够访问他的视频。我尝试了加密和解密,但视频文件太大 (1GB),需要花费很多时间。

你们有什么想法我该怎么办?

请在下面找到我的加密和解密代码:

 private File sdCardRoot;
private ProgressBar progressBar;

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

    sdCardRoot = Environment.getExternalStorageDirectory();
    Button encrypt = findViewById(R.id.zip);
    Button dencrypt = findViewById(R.id.unzip);
    progressBar = findViewById(R.id.progress);

    encrypt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            progressBar.setVisibility(View.VISIBLE);
            try {
                Log.e("file", "try");
                encryption();
            } catch (Exception e) {
                Log.e("file", "catch" + String.valueOf(e));

                e.printStackTrace();
            }
        }
    });

    dencrypt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            progressBar.setVisibility(View.VISIBLE);
            try {
                dcryption();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

}

private void dcryption() throws Exception {
    progressBar.setVisibility(View.VISIBLE);
    String password = "javapapers";

    // reading the salt
    // user should have secure mechanism to transfer the
    // salt, iv and password to the recipient
    File fileSalt = new File(sdCardRoot, "/salt.enc");
    FileInputStream saltFis = new FileInputStream(fileSalt);
    byte[] salt = new byte[8];
    saltFis.read(salt);
    saltFis.close();

    // reading the iv
    File fileIv = new File(sdCardRoot, "/iv.enc");
    FileInputStream ivFis = new FileInputStream(fileIv);
    byte[] iv = new byte[16];
    ivFis.read(iv);
    ivFis.close();

    SecretKeyFactory factory = SecretKeyFactory
            .getInstance("PBKDF2WithHmacSHA1");
    KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536,
            256);
    SecretKey tmp = factory.generateSecret(keySpec);
    SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

    // file decryption
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
    File oldFile = new File(sdCardRoot, "/wp.mp4");
    File oldFile1 = new File(sdCardRoot, "/w.des");
    FileInputStream fis = new FileInputStream(oldFile1);
    FileOutputStream fos = new FileOutputStream(oldFile);
    byte[] in = new byte[64];
    int read;
    while ((read = fis.read(in)) != -1) {
        byte[] output = cipher.update(in, 0, read);
        if (output != null)
            fos.write(output);
    }

    byte[] output = cipher.doFinal();
    if (output != null) {
        fos.write(output);
        fis.close();
        fos.flush();
        fos.close();
    }
    if (fileIv.exists() && fileSalt.exists() && oldFile1.exists()) {
        fileIv.delete();
        fileSalt.delete();
        oldFile1.delete();
    }
    progressBar.setVisibility(View.GONE);
    System.out.println("File Decrypted.");
}


private void encryption() throws Exception {

    File oldFile = new File(sdCardRoot, "/w.mp4");
    File oldFile1 = new File(sdCardRoot, "/w.des");

    Log.e("file", String.valueOf(oldFile));
    FileInputStream inFile = new FileInputStream(oldFile);
    Log.e("file", String.valueOf(inFile));
    // encrypted file
    FileOutputStream outFile = new FileOutputStream(oldFile1);
    Log.e("file", String.valueOf(outFile));

    // password to encrypt the file
    String password = "javapapers";

    // password, iv and salt should be transferred to the other end
    // in a secure manner

    // salt is used for encoding
    // writing it to a file
    // salt should be transferred to the recipient securely
    // for decryption
    byte[] salt = new byte[8];
    SecureRandom secureRandom = new SecureRandom();
    secureRandom.nextBytes(salt);
    Log.e("file", "a");
    File fileSalt = new File(sdCardRoot, "/salt.enc");

    FileOutputStream saltOutFile = new FileOutputStream(fileSalt);
    Log.e("file", "b");

    saltOutFile.write(salt);
    saltOutFile.close();

    SecretKeyFactory factory = SecretKeyFactory
            .getInstance("PBKDF2WithHmacSHA1");
    KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536,
            256);
    SecretKey secretKey = factory.generateSecret(keySpec);
    SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

    //
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secret);
    AlgorithmParameters params = cipher.getParameters();

    // iv adds randomness to the text and just makes the mechanism more
    // secure
    // used while initializing the cipher
    // file to store the iv
    Log.e("file", "c");
    File fileIv = new File(sdCardRoot, "/iv.enc");

    FileOutputStream ivOutFile = new FileOutputStream(fileIv);
    Log.e("file", "d");
    byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
    ivOutFile.write(iv);
    ivOutFile.close();

    //file encryption
    byte[] input = new byte[64];
    int bytesRead;

    while ((bytesRead = inFile.read(input)) != -1) {
        byte[] output = cipher.update(input, 0, bytesRead);
        if (output != null)
            outFile.write(output);
    }

    byte[] output = cipher.doFinal();
    if (output != null)
        outFile.write(output);

    inFile.close();
    outFile.flush();
    outFile.close();

    if (oldFile.exists()) {
        oldFile.delete();
    }

    System.out.println("File Encrypted.");

}

最佳答案

使用下面的代码:

import java.io.File;
import java.io.RandomAccessFile;

public class VideoCrypt {
    public static final int REVERSE_BYTE_COUNT = 1024;

    public static boolean decrypt(String path) {
        try {
            if (path == null) return false;
            File source = new File(path);
            int byteToReverse = source.length() < REVERSE_BYTE_COUNT ? ((int) source.length()) : REVERSE_BYTE_COUNT;
            RandomAccessFile f = new RandomAccessFile(source, "rw");
            f.seek(0);
            byte b[] = new byte[byteToReverse];
            f.read(b);
            f.seek(0);
            reverseBytes(b);
            f.write(b);
            f.seek(0);
            b = new byte[byteToReverse];
            f.read(b);
            f.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean encrypt(String path) {
        try {
            if (path == null) return false;
            File source = new File(path);
            RandomAccessFile f = new RandomAccessFile(source, "rw");
            f.seek(0);
            int byteToReverse = source.length() < REVERSE_BYTE_COUNT ? ((int) source.length()) : REVERSE_BYTE_COUNT;
            byte b[] = new byte[byteToReverse];
            f.read(b);
            f.seek(0);
            reverseBytes(b);
            f.write(b);
            f.seek(0);
            b = new byte[byteToReverse];
            f.read(b);
            f.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private static void reverseBytes(byte[] array) {
        if (array == null) return;
        int i = 0;
        int j = array.length - 1;
        byte tmp;
        while (j > i) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
            j--;
            i++;
        }
    }
}

关于java - 如何加密和解密大视频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59961064/

相关文章:

android - 在 android 中解析 KSoap2 响应

java - 如何在抽屉导航中显示图像

android - 为什么 youtube 视频在播放时会强制关闭应用程序?

java - Aspectj 声明错误无法正常工作

java - 将 Owl 类转换为 java 类或 xml

java - 没有检索到 GPS 更新?代码有问题?

android - 使用 Retrofit 从服务器读取纯文本响应

java - 在 Java 中编写注释来约束类/方法命名?

java - Camel JPA @Consumed 替代品

java - 将 java 应用程序与在线托管的 mysql 数据库连接