Video Encryption and Decryption in Android

Hi friends,

Today I will write about the video encryption and decryption in android.
In video encryption we convert a sample video into a encrypted format that cannot be played by any media player. It can only be played after the decryption of that video using private key.
We encrypt the video by encrypting the small chunks of video one by one since the issue of memory constraint in Android.
If we had to encrypt the whole file we have to load the complete file into RAM which would have caused "OutOfMemoryEncryption" leading to crash.

Here is the Encrypter class i have created for Encrypting and Decrypting the video files.

In Encrypt method we have 4 parameters-

1.Secret Key      -----  key used to encrypt and decrypt file

2.AlgorithParameterSpec     ----  parameter required for algorithm used in this process

3.Input Stream   ------ Video file in Input stream format

4.Output Stream     ------   decrypted video file from the encrypted file

public class Encrypter {
    private final static int DEFAULT_READ_WRITE_BLOCK_BUFFER_SIZE = 1024;
    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 {
            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 {
            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();
        }
    }
}

Now we use this class in our MainActivity to decrypt and encrypt video files.

Here I access video files of my phone and store in a arraylist named "listOfVideo".
I use "path" variable to store a particular video path saved our phone's sdcard.
Then i created 3 files namely  ---
1. InFile
2. OutFile
3. OutFile Dec

"InFile" is the video file we have to encrypted.
"OutFile" is the encrypted file afer encryption process.
"OutFile Dec" is the decrypted video file from the one we encrypted so we can play this video.

Then We use a automatically generated SecretKey "key" that we have generated using Algorithm "AES".Now we have to store this key to use it later in decrypting the video file. I store it in "keyData"
"key2" is generated from this "keyData" and used in decrypting the video we have encrypted.

At last we have to generate initialization vector "iv" to create  the AlgorithParameterSpec parameter of algorithm
And now we use the Encrpyt and Decrypt methods of Encryptor class to First encrypt the video and then decrypt it...............

public class MainActivity extends AppCompatActivity {
    private final static String ALGO_RANDOM_NUM_GENERATOR = "SHA1PRNG";
    private final static String ALGO_SECRET_KEY_GENERATOR = "AES";
    private final static int IV_LENGTH = 16;
    Cursor mVideoCursor;
    ArrayList<HashMap<String, String>> listOfVideo;
    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listOfVideo = new ArrayList();
        String[] videoColumns = {MediaStore.Video.Media.DATA,MediaStore.Video.Media.DURATION,
        MediaStore.Video.Media.SIZE,MediaStore.Video.Media.DISPLAY_NAME};
        mVideoCursor = getApplicationContext().getContentResolver().query
                (MediaStore.Video.Media.EXTERNAL_CONTENT_URI, videoColumns, null, null, null);
        mVideoCursor.moveToFirst();
        for (int i = 0; i < mVideoCursor.getCount(); i++) {
            listOfVideo.add(new HashMap<String, String>() {
                {
                    put("data", String.valueOf(mVideoCursor.getString( 
                    mVideoCursor.getColumnIndex(MediaStore.Video.Media.DATA))));
                    put("duration", String.valueOf(mVideoCursor.getString(
                    mVideoCursor.getColumnIndex(MediaStore.Video.Media.DURATION))));
                    put("displayName", String.valueOf(mVideoCursor.getString(
                    mVideoCursor.getColumnIndex(MediaStore.Video.Media.DISPLAY_NAME))));
                    put("size", String.valueOf(mVideoCursor.getString(
                    mVideoCursor.getColumnIndex(MediaStore.Video.Media.SIZE))));
                    mVideoCursor.moveToNext();

                }
            });
        }
 
        String path = listOfVideo.get(0).get("data");
        File inFile = new File(listOfVideo.get(0).get("data"));
        File outFile = new File(path.substring(0, path.lastIndexOf("/"))+"/enc_video.swf");
        File outFile_dec = new File(path.substring(0, path.lastIndexOf("/"))+"/dec_video.mp4");

        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);  
            byte[] iv = new byte[IV_LENGTH];
            SecureRandom.getInstance(ALGO_RANDOM_NUM_GENERATOR).nextBytes(iv);
            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!!!!!!!
You can refer to my repository on Github for more source code -
 https://github.com/akash-bisariya/Video-Encryption-Decryption





Create Custom Twitter Follow Button in Android Application

Hello friends ,
Today i am going to post my second tutorial.

In this tutorial I will explain how to create the custom "Twitter Follow" button in our android application.

With this button we can the follow the particular person on twitter.
For this you have to first integrate Fabric API provided by Twitter. Here is a link to integrate this api -  https://get.fabric.io/
There are several simple to steps integrate this api and you can use Twitter Login feature in just few steps by using it.
Now we see how to create Follow Functionality in our application.
First you have to create a simple "Follow Me"button in layout of the activity on which click event we have to implement Follow functionality.
(Note - I am assuming user is already logged in twitter  using Fabric API).

I am creating a class "TwitterFollowMe" and a interface to hit twitter api of following a person as -

public class TwitterFollowMe extends TwitterApiClient {
    public TwitterFollowMe(TwitterSession session) {
        super(session);
    }
    public FollowService getFollowService() {
        return getService(FollowService.class);
    }
    /*interface used for Api call for Following*/
    public interface FollowService {
        @POST("/1.1/friendships/create.json")
        public void create(@Query("screen_name") String screen_name,
        @Query("user_id") String user_id, @Query("friends") boolean follow, 
        Callback<User> cb);
    }
}

Now on "Follow Me" button click event you have to implement that interface as -

btnFollowMe.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        apiClient = new TwitterFollowMe(session);
        //twitter user name
        apiClient.getFollowService().create("Twitter_Screen_Name(ex-Moto_IND)", 
        null, true, new Callback<User>() {
            @Override
            public void success(Result<User> result) {
                Toast.makeText(MainActivity.this, "Thanks for following!", 
                Toast.LENGTH_SHORT).show();
                btnFollowMe.setVisibility(View.GONE);
            }

            @Override
            public void failure(TwitterException e) {
                Toast.makeText(MainActivity.this, "Error following", 
                Toast.LENGTH_SHORT).show();
            }
        });
    }
});

In this code we call "getFollowService().create" method .
First parameter is the "Twitter Screen Name" of the user and the second parameter is "Twitter User Id" and the third parameter is boolean to indicate Follow action and the last is the Callback.
You can provide any one parameter from the  "User Id" and "Screen Name".
In "success" callback you can get the call after successfully following that "Twitter User".

And that's all to implement the Twitter Follow button!!!!.

Thanks

Flutter : Using Form and Text Fields

Flutter is a popular cross-platform mobile development framework that allows developers to build native apps for both Android and iOS using ...