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
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/
Comments
-
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 about 12 yearsIt shouldn't take that much amount of tym....i guess your file is huge....how long is it??
-
Shashank Kadne about 12 yearsencryption shouldn't take much amount of time....You are doing encryption/decryption both ?..Then the time will get doubled..
-
png almost 12 yearsNavdroid : 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 almost 12 years@preetha: I think it depends on the processing power. Did you try it on a real device ?
-
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 over 11 yearsAnd how are you going to play the encrypted video again, without exposing it in unencrypted form?
-
Shashank Kadne over 11 years@Chris: That is just for storing them. Before playing ofcourse we need to decrypt it.
-
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_ over 10 yearsYou 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 almost 10 years@ChrisStratton very nice and interesting point made by you. Just wanted to know if you had any luck on this?
-
Anish almost 10 yearsCan anyone tell me how many bits encryption is this? If default then how many?
-
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 ofKeyGenerator
Eg:kgen.init(256);
-
Sai almost 9 yearsAwesome work.Thank you very much. For some reason
AES/CBC/PKCS5Padding
dose not work for me, changing it toAES
worked... -
Artjom B. over 7 yearsGeneral 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. over 7 yearsIt'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_ 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. over 7 yearsSorry if I was unclear. It's better to remove the
AlgorithmParameterSpec
(IV) argument from the method signatures ofencrypt
anddecrypt
and instead: inencrypt
generate a fresh IV, write it to the output stream and use it for encryption and indecrypt
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_ over 7 yearsThanks 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 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 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 about 7 years@AZ_ How you plan to decrypt and play them, without exposing the decrypted version to copying?
-
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 about 7 years@AZ_ Thanks for commenting back, Right now I am using this library to play decrypted video libeasy.alwaysdata.net