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

Swipe and Dismiss Behavior in Views of Android

Hi Friends.
I am back!!(May be some late).
I will post my first tutorial of android.
Here I will discuss about how to give swipe and dismiss functionality to our views or layouts.
This feature introduces with the "Design support Library" that includes a public class called "SwipeDismissBehavior" that can be easily used with Coordinator layout to implement this functionality.
Following is layout of my simple page that has a parent coordinator layout and linear layout as a child.Linear layout contains a image view and text view.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout    
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:layout_gravity="bottom"
    tools:context="com.affle.coordinatorlayoutexa.MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:orientation="horizontal"
        android:weightSum="2"
        android:id="@+id/llContainer"
        android:gravity="bottom">
        <ImageView
            android:layout_width="0dp"
            android:layout_height="150dp"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
            android:src="@drawable/imgpsh_fullsize"
            android:id="@+id/ivIamge"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="This view is for swipped and dismiss"/>
    </LinearLayout>
</android.support.design.widget.CoordinatorLayout>





Following is my main activity that uses the "SwipeDismissBehaviour" class.
First we have to create instance of this class as - 




SwipeDismissBehavior<LinearLayout> swipeDismissBehavior = new SwipeDismissBehavior<>();
Then we set the direction of swiping as - 
swipeDismissBehavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_START_TO_END);
Now we set the listener of swipe event that includes two override methods - 
1. OnDismiss()
2. OnDragStateChanged
swipeDismissBehavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
    @Override    public void onDismiss(View view) {
        Toast.makeText(MainActivity.this,
                "View swiped ", Toast.LENGTH_SHORT).show();}
    @Override    public void onDragStateChanged(int state) {}
});
And at last we find the LayoutParams of the parent layout and set its behavior as -
CoordinatorLayout.LayoutParams params=(CoordinatorLayout.LayoutParams)llContainer.getLayoutParams();
params.setBehavior(swipeDismissBehavior);

And that's all we have to do!!!
Enjoy the Swipe and Dismiss feature.






Hi Friends,
Have a nice day !!
My name is Akash and I am an Android Developer. I am not a experienced developer but i must say myself a learning developer.
Now on wards i will share some of my coding experiences with you , as this platform is an ideal choice for sharing knowledge and experience.
You must also share your experiences as we all know that knowledge increases with sharing!

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 ...