Encryption of video files?

24,462

Solution 1

CipherInputStream and CipherOutputStream will help you do that easily. I wrote a sample program to encrypt and decrypt a video file. Modify it as per your choice...

FileInputStream fis = new FileInputStream(new File("D:/Shashank/inputVideo.avi"));
        File outfile = new File("D:/Shashank/encVideo.avi");
        int read;
        if(!outfile.exists())
            outfile.createNewFile();
        File decfile = new File("D:/Shashank/decVideo.avi");
        if(!decfile.exists())
            decfile.createNewFile();
        FileOutputStream fos = new FileOutputStream(outfile);
        FileInputStream encfis = new FileInputStream(outfile);
        FileOutputStream decfos = new FileOutputStream(decfile);
        Cipher encipher = Cipher.getInstance("AES");
        Cipher decipher = Cipher.getInstance("AES");
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        //byte key[] = {0x00,0x32,0x22,0x11,0x00,0x00,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        SecretKey skey = kgen.generateKey();
        //Lgo
        encipher.init(Cipher.ENCRYPT_MODE, skey);
        CipherInputStream cis = new CipherInputStream(fis, encipher);
        decipher.init(Cipher.DECRYPT_MODE, skey);
        CipherOutputStream cos = new CipherOutputStream(decfos,decipher);
        while((read = cis.read())!=-1)
                {
                    fos.write((char)read);
                    fos.flush();
                }   
        fos.close();
        while((read=encfis.read())!=-1)
        {
            cos.write(read);
            cos.flush();
        }
    cos.close(); 

I am generating a new key using generateKey(). You can use a byte array too, to generate your own key....

Solution 2

Encryption Major Mistakes

Tonyz Java AES Encryptor

Fast encryption/Decryption with Random IV generation using Java SecureRandom

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Encrypter {
    private final static int IV_LENGTH = 16; // Default length with Default 128
                                                // key AES encryption
    private final static int DEFAULT_READ_WRITE_BLOCK_BUFFER_SIZE = 1024;

    private final static String ALGO_RANDOM_NUM_GENERATOR = "SHA1PRNG";
    private final static String ALGO_SECRET_KEY_GENERATOR = "AES";
    private final static String ALGO_VIDEO_ENCRYPTOR = "AES/CBC/PKCS5Padding";

    @SuppressWarnings("resource")
    public static void encrypt(SecretKey key, /*AlgorithmParameterSpec paramSpec,*/ InputStream in, OutputStream out)
            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
            InvalidAlgorithmParameterException, IOException {
        try {
            // byte[] iv = new byte[] { (byte) 0x8E, 0x12, 0x39, (byte) 0x9C,
            // 0x07, 0x72, 0x6F, 0x5A, (byte) 0x8E, 0x12, 0x39, (byte) 0x9C,
            // 0x07, 0x72, 0x6F, 0x5A };
            //generate new AlgorithmParameterSpec 
            // AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
            Cipher c = Cipher.getInstance(ALGO_VIDEO_ENCRYPTOR);
            c.init(Cipher.ENCRYPT_MODE, key, paramSpec);
            out = new CipherOutputStream(out, c);
            int count = 0;
            byte[] buffer = new byte[DEFAULT_READ_WRITE_BLOCK_BUFFER_SIZE];
            while ((count = in.read(buffer)) >= 0) {
                out.write(buffer, 0, count);
            }
        } finally {
            out.close();
        }
    }

    @SuppressWarnings("resource")
    public static void decrypt(SecretKey key, /*AlgorithmParameterSpec paramSpec,*/ InputStream in, OutputStream out)
            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
            InvalidAlgorithmParameterException, IOException {
        try {
            // byte[] iv = new byte[] { (byte) 0x8E, 0x12, 0x39, (byte) 0x9C,
            // 0x07, 0x72, 0x6F, 0x5A, (byte) 0x8E, 0x12, 0x39, (byte) 0x9C,
            // 0x07, 0x72, 0x6F, 0x5A };
            // read from input stream AlgorithmParameterSpec 
            // AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
            Cipher c = Cipher.getInstance(ALGO_VIDEO_ENCRYPTOR);
            c.init(Cipher.DECRYPT_MODE, key, paramSpec);
            out = new CipherOutputStream(out, c);
            int count = 0;
            byte[] buffer = new byte[DEFAULT_READ_WRITE_BLOCK_BUFFER_SIZE];
            while ((count = in.read(buffer)) >= 0) {
                out.write(buffer, 0, count);
            }
        } finally {
            out.close();
        }
    }

    public static void main(String[] args) {
        File inFile = new File("C:/enc_test/video.swf");
        File outFile = new File("C:/enc_test/enc_video.swf");
        File outFile_dec = new File("C:/enc_test/dec_video.swf");

        try {
            SecretKey key = KeyGenerator.getInstance(ALGO_SECRET_KEY_GENERATOR).generateKey();

            byte[] keyData = key.getEncoded();
            SecretKey key2 = new SecretKeySpec(keyData, 0, keyData.length, ALGO_SECRET_KEY_GENERATOR); //if you want to store key bytes to db so its just how to //recreate back key from bytes array

            byte[] iv = new byte[IV_LENGTH];
            SecureRandom.getInstance(ALGO_RANDOM_NUM_GENERATOR).nextBytes(iv); // If
                                                                                // storing
                                                                                // separately
            AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);

            Encrypter.encrypt(key, paramSpec, new FileInputStream(inFile), new FileOutputStream(outFile));
            Encrypter.decrypt(key2, paramSpec, new FileInputStream(outFile), new FileOutputStream(outFile_dec));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

Thanks Naveem M kumar for suggestion http://libeasy.alwaysdata.net/

Share:
24,462
Navdroid
Author by

Navdroid

WORLD IS YOURS

Updated on April 13, 2020

Comments

  • Navdroid
    Navdroid about 4 years

    I am using this method for encrypting a video file:

    public static void encryptToBinaryFile(String password, byte[] bytes, File file) throws EncrypterException {
        try {
            final byte[] rawKey = getRawKey(password.getBytes());
            final FileOutputStream ostream = new FileOutputStream(file, false);
    
            ostream.write(encrypt(rawKey, bytes));
            ostream.flush();
            ostream.close();
    
        } catch (IOException e) {
            throw new EncrypterException(e);
        }
    }
    
    private static byte[] encrypt(byte[] raw, byte[] clear) throws EncrypterException {
        try {
           final SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
           final Cipher cipher = Cipher.getInstance("AES");
           cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    
           return cipher.doFinal(clear);
    
        } catch (Exception e) {
            throw new EncrypterException(e);
        }
    }
    

    But It gives an error Outofmemoryerror saying rejecting allocation of 301023321 element.

    1.Is the method I am using correct for such big files?

    2.If yes why I am getting this error?What is solution?

    3.If no please suggest some good method for that?

  • Shashank Kadne
    Shashank Kadne about 12 years
    It shouldn't take that much amount of tym....i guess your file is huge....how long is it??
  • Shashank Kadne
    Shashank Kadne about 12 years
    encryption shouldn't take much amount of time....You are doing encryption/decryption both ?..Then the time will get doubled..
  • png
    png almost 12 years
    Navdroid : did you find a way to speed up this. I am facing the same issue. whatever way i try, as the file size increase, the time taken is huge
  • Shashank Kadne
    Shashank Kadne almost 12 years
    @preetha: I think it depends on the processing power. Did you try it on a real device ?
  • Shashank Kadne
    Shashank Kadne almost 12 years
    @preetha: I wrote the above program for a Desktop application. The time taken was equal to the time it takes to copy a video from one drive to another. Can you tell me the time difference between 1)Copying a video from one folder to another on device and 2)Creating an encrypted video on the destination folder on your device ?
  • Chris Stratton
    Chris Stratton over 11 years
    And how are you going to play the encrypted video again, without exposing it in unencrypted form?
  • Shashank Kadne
    Shashank Kadne over 11 years
    @Chris: That is just for storing them. Before playing ofcourse we need to decrypt it.
  • Chris Stratton
    Chris Stratton over 11 years
    @ShashankKadne - of course, but the really interesting question is how you plan to decrypt and play them, without exposing the decrypted version to copying.
  • AZ_
    AZ_ over 10 years
    You are using Character Stream while reading and encrypting and it is very slow instead you can use buffer and read line by line to increase speed like this byte[] buffer = new byte[1024]; while ((count = in.read(buffer)) >= 0) { out.write(buffer, 0, count); }
  • Anish
    Anish almost 10 years
    @ChrisStratton very nice and interesting point made by you. Just wanted to know if you had any luck on this?
  • Anish
    Anish almost 10 years
    Can anyone tell me how many bits encryption is this? If default then how many?
  • Shashank Kadne
    Shashank Kadne almost 10 years
    @anish : It looks like the default key size is 128 bits(16 bytes). If you want, you can change it using the init method of KeyGenerator Eg: kgen.init(256);
  • Sai
    Sai almost 9 years
    Awesome work.Thank you very much. For some reason AES/CBC/PKCS5Padding dose not work for me, changing it to AES worked...
  • Artjom B.
    Artjom B. over 7 years
    General advice: Always use a fully qualified Cipher string. Cipher.getInstance("AES"); may result in different ciphers depending on the default security provider. It most likely results in "AES/ECB/PKCS5Padding", but it doesn't have to be. If it changes, you'll lose compatibility between different JVMs. For reference: Java default Crypto/AES behavior
  • Artjom B.
    Artjom B. over 7 years
    It's sometimes better to show opinionated code, because most readers won't get it right. The IV is not secret, so you can send it along with the ciphertext. Usually, it is simply prepended to the ciphertext and sliced off before decryption.
  • AZ_
    AZ_ over 7 years
    @ArtjomB. I have declared IV_Length in class variable, IV_LENGTH = 16. I hope I have correctly understand your question
  • Artjom B.
    Artjom B. over 7 years
    Sorry if I was unclear. It's better to remove the AlgorithmParameterSpec (IV) argument from the method signatures of encrypt and decrypt and instead: in encrypt generate a fresh IV, write it to the output stream and use it for encryption and in decrypt read the IV from the input stream and use it for decryption. That way, future readers wouldn't need to care about the IV by themselves and won't get it wrong and it's easy to get wrong.
  • AZ_
    AZ_ over 7 years
    Thanks for clearing misunderstanding, I have updated the solution, if there is something still needs to be changed, please you can do it : ) Thanks.
  • Naveen Kumar M
    Naveen Kumar M about 7 years
    @Shashank Kadne : After Encrypt need to use same skey for decrypt? Or I can generate new one? If I need use same key I need to store that also
  • Shashank Kadne
    Shashank Kadne about 7 years
    @Naveen Kumar M: Yes as AES is Symmetric kry cryptography, the key used for both Encryption and Decryption are same. RSA uses public and private key so you may want to check that.
  • Naveen Kumar M
    Naveen Kumar M about 7 years
    @AZ_ How you plan to decrypt and play them, without exposing the decrypted version to copying?
  • AZ_
    AZ_ about 7 years
    @NaveenKumarM if your future frames does not depend on your past frames then you can divide video into blocks and read block by block say 1 MB is one block, read more blocks as you go on and destroy previous blocks because you cannot put all the video in the memory, this code is just scratching the surface.
  • Naveen Kumar M
    Naveen Kumar M about 7 years
    @AZ_ Thanks for commenting back, Right now I am using this library to play decrypted video libeasy.alwaysdata.net