Blogger Widgets
Subscribe:

Ads 468x60px

get in touch with google@dhanoopbhaskar.in

Sunday, August 11, 2013

Java - Encryption and Decryption of an Image Using Blowfish Algorithm

 
EncryptFile.java
 
package com.java.blowfish;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

/**
 *
 * @author dhanoopbhaskar
 */
public class EncryptFile {

    KeyGenerator keyGenerator = null;
    SecretKey secretKey = null;
    Cipher cipher = null;

    public EncryptFile() {
        try {
            /**
             * Create a Blowfish key
             */
            keyGenerator = KeyGenerator.getInstance("Blowfish");
            secretKey = keyGenerator.generateKey();

            /**
             * Create an instance of cipher mentioning the name of algorithm
             *     - Blowfish
             */
            cipher = Cipher.getInstance("Blowfish");
        } catch (NoSuchPaddingException ex) {
            System.out.println(ex);
        } catch (NoSuchAlgorithmException ex) {
            System.out.println(ex);
        }
    }

    public static void main(String[] args) {
        String fileToEncrypt = "fileToEncrypt.jpg";
        String encryptedFile = "encryptedFile.jpg";
        String decryptedFile = "decryptedFile.jpg";
        String directoryPath = "C:/Users/dhanoopbhaskar/Desktop/blowfish/";
        EncryptFile encryptFile = new EncryptFile();
        System.out.println("Starting Encryption...");
        encryptFile.encrypt(directoryPath + fileToEncrypt,
                directoryPath + encryptedFile);
        System.out.println("Encryption completed...");
        System.out.println("Starting Decryption...");
        encryptFile.decrypt(directoryPath + encryptedFile,
                directoryPath + decryptedFile);
        System.out.println("Decryption completed...");
    }

    /**
     * 
     * @param srcPath
     * @param destPath
     *
     * Encrypts the file in srcPath and creates a file in destPath
     */
    private void encrypt(String srcPath, String destPath) {
        File rawFile = new File(srcPath);
        File encryptedFile = new File(destPath);
        InputStream inStream = null;
        OutputStream outStream = null;
        try {
            /**
             * Initialize the cipher for encryption
             */
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            /**
             * Initialize input and output streams
             */
            inStream = new FileInputStream(rawFile);
            outStream = new FileOutputStream(encryptedFile);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inStream.read(buffer)) > 0) {
                outStream.write(cipher.update(buffer, 0, len));
                outStream.flush();
            }
            outStream.write(cipher.doFinal());
            inStream.close();
            outStream.close();
        } catch (IllegalBlockSizeException ex) {
            System.out.println(ex);
        } catch (BadPaddingException ex) {
            System.out.println(ex);
        } catch (InvalidKeyException ex) {
            System.out.println(ex);
        } catch (FileNotFoundException ex) {
            System.out.println(ex);
        } catch (IOException ex) {
            System.out.println(ex);
        }
    }

    /**
     * 
     * @param srcPath
     * @param destPath
     *
     * Decrypts the file in srcPath and creates a file in destPath
     */
    private void decrypt(String srcPath, String destPath) {
        File encryptedFile = new File(srcPath);
        File decryptedFile = new File(destPath);
        InputStream inStream = null;
        OutputStream outStream = null;
        try {
            /**
             * Initialize the cipher for decryption
             */
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            /**
             * Initialize input and output streams
             */
            inStream = new FileInputStream(encryptedFile);
            outStream = new FileOutputStream(decryptedFile);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inStream.read(buffer)) > 0) {
                outStream.write(cipher.update(buffer, 0, len));
                outStream.flush();
            }
            outStream.write(cipher.doFinal());
            inStream.close();
            outStream.close();
        } catch (IllegalBlockSizeException ex) {
            System.out.println(ex);
        } catch (BadPaddingException ex) {
            System.out.println(ex);
        } catch (InvalidKeyException ex) {
            System.out.println(ex);
        } catch (FileNotFoundException ex) {
            System.out.println(ex);
        } catch (IOException ex) {
            System.out.println(ex);
        }
    }
}

Output: 
Starting Encryption... 
Encryption completed... 
Starting Decryption... 
Decryption completed...


Before Encryption

After Encryption


The method doFinal() should not be used in loop or repeatedly. If we have to encrypt/decrypt multiple blocks we use update() method.
 
outStream.write(cipher.update(buffer, 0, len));

After everything is done we call doFinal() method.
 
outStream.write(cipher.doFinal());

If we use doFinal repeatedly, the encryption will work without errors. But decryption will fail throwing exception - javax.crypto.BadPaddingException

See related posts:
Java - Encryption and Decryption of an Image Using Blowfish Algorithm (using password)
Java - Encryption and Decryption of an Image Using Another Image (Blowfish Algorithm)

34 comments:

  1. Hi,
    I want to encrypt file somewhere and decrypt file somewhere else.
    So, How to replace
    secretKey = keyGenerator.generateKey();
    with something like
    secretKey = getKeyObjectFromPassword("my_password");

    ReplyDelete
  2. Hi Victor,

    You can replace the following statements

    keyGenerator = KeyGenerator.getInstance("Blowfish");
    secretKey = keyGenerator.generateKey();

    with

    secretKey = new SecretKeySpec(masterPassword.getBytes(), "Blowfish");
    //import javax.crypto.spec.SecretKeySpec; should be used.

    where masterPassword is the password given.

    Regards,
    Dhanoop Bhaskar

    ReplyDelete
  3. i am not getting encrypted image. when i open the encrypted image it opens saying invalid file format/invalid image. please help me out

    ReplyDelete
    Replies
    1. Hi Anusha,
      Before running the program you will have to modify the directory path and the file names used (in the main function). None of the applications could open an encrypted image as such; the process of encryption manipulates the file at bit-level.
      However you should be able to open the encrypted file after decryption. Please let me know if you have some other concerns.

      Regards,
      Dhanoop Bhaskar

      Delete
    2. hello ,she is saying encryption one image over another image pa.
      only one path is specfide

      Delete
  4. Hi,
    In the given program, the file "fileToEncrypt.jpg" is encrypted to get "encryptedFile.jpg". After that "encryptedFile.jpg" is decrypted and we get "decryptedFile.jpg".
    The files "fileToEncrypt.jpg" and "decryptedFile.jpg" will be identical.
    Dhanoop Bhaskar

    ReplyDelete
    Replies
    1. HI ,
      I understand coding ,but i want help, tat is encrypt "filetoEncrypt"to another image?? how to do it

      Delete
    2. Hi,
      An image on encryption would not give another image which is viewable by some application. It is literally impossible for an application to read the encrypted image file as an "image". The encoding is totally altered on encryption, so that it becomes unreadable. Decryption makes it back in a readable form.

      Regards,
      Dhanoop Bhaskar

      Delete
  5. please help bro my code is based on "AES". it encrypt everything (image ,video,ppt etc) the problem is encryption with image not encrypted

    ReplyDelete
    Replies
    1. Hi,
      Please do the following changes in the above program so that it does "AES" encryption and decryption.

      Replace

      keyGenerator = KeyGenerator.getInstance("Blowfish");

      by

      keyGenerator = KeyGenerator.getInstance("AES");

      AND

      cipher = Cipher.getInstance("Blowfish");

      by

      cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

      Regards,
      Dhanoop Bhaskar

      Delete
  6. no that know .encryption image to another image ;
    ex : input file 1 - filetoencypt
    input file 2- images to encrypt file 1
    out put - encrypt image

    ReplyDelete
    Replies
    1. Hi Shakthi,
      Please see whether this is what you want- http://www.theinsanetechie.in/2014/04/java-encryption-and-decryption-of-image_9.html

      Delete
  7. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Hi Ciaran,

      It is already there in the comments. A similar question was asked before, by another person.
      Instead of auto-generating the key for encryption and decryption, we can provide a password, from which the key will be derived.

      You can replace the following statements

      keyGenerator = KeyGenerator.getInstance("Blowfish");
      secretKey = keyGenerator.generateKey();

      with

      secretKey = new SecretKeySpec(masterPassword.getBytes(), "Blowfish");
      //import javax.crypto.spec.SecretKeySpec; should be used.

      where masterPassword is the password given.

      You can find the complete program here-
      http://www.theinsanetechie.in/2014/04/java-encryption-and-decryption-of-image.html

      Delete
  8. Could u plz tel me what would be the inputs for blowfish algorithm where i want to do encryption as well as decryption on watermark i;e an image .Since my project is on digital image watermarking where i m using blowfish algorithm to make my watermark (which is an image )encrypted for the security purpose so no one can make any modification to dat.

    ReplyDelete
    Replies
    1. Hi Vandana,
      The inputs to the blowfish algorithm include the image to be encrypted and the password with which the image is to be encrypted. However, the password is optional; you can auto-generate the secret key instead of deriving it from a user supplied password.

      Delete
    2. thnkz fr rply bt plz tel me dat how to convert an image in to 64 bits....since an image is in matrix form so we can take a block of an image and if i take a block then how i do the operation like XORing (bit wise).........answer me asap

      Delete
    3. Please tell me why do you need to convert an image into 64 bits. If you mean the block size, it is not needed here. The JCE (Java Cryptography Extension) abstracts such complexities from the user. We need not bother about the block size, the permutations and substitution applied, etc.

      while ((len = inStream.read(buffer)) > 0) {
      outStream.write(cipher.update(buffer, 0, len));
      outStream.flush();
      }
      outStream.write(cipher.doFinal());

      The above code snippet reads the file in multiples of 1024 bytes, (given so as to support large files without consuming much memory, you may also take all the available bytes in one read operation), encrypt (or decrypt) it - using the cipher part - and writes to another file.

      Delete
  9. Sir.. do you have the corresponding Android code??

    ReplyDelete
  10. Sir.. do you have the corresponding Android code??

    ReplyDelete
    Replies
    1. Hi Meenu,
      You can use the same code in android also :)

      Delete
    2. How can I change the code that the image uploaded by the user can be used as the input and then encrypt and decrypt?

      Delete
    3. For that you will have to implement it in a Servlet.

      Delete
  11. in this code have come this error please reply me
    Starting Encryption...
    java.io.FileNotFoundException: F:\Images\fileToEncrypt.jpg (The system cannot find the file specified)
    Encryption completed...
    Starting Decryption...
    java.io.FileNotFoundException: F:\Images\encryptedFile.jpg (The system cannot find the file specified)
    Decryption completed.




    i am put the directory right but thing is the thius code not use \ for directory to / this

    ReplyDelete
    Replies
    1. Hi Maulik,
      Hope you use windows.
      In my case the above program worked. Ideally "/" should work in Windows as well as Linux platforms.

      String fileToEncrypt = "fileToEncrypt.jpg";
      /*The image should have the name fileToEncrypt.jpg */

      Modify the statement as given below, and try re-running the program.

      String directoryPath = "F:\\Images\\";
      /* The image fileToEncrypt.jpg should be placed in path F:\Images\ */


      If you are using Linux, the statement may look like-
      String directoryPath = "/home/dhanoopbhaskar/Pictures/";
      /* where image is in the path /home/dhanoopbhaskar/Pictures/fileToEncrypt.jpg */

      Delete
  12. Repsected Sir Thanks For you reply
    i am use Window and i am change don this provided by you but the problem is not solve please help me sir

    ReplyDelete
    Replies
    1. Please share your version of the program and the image used to my email id - dhanoopbhaskar@gmail.com

      Delete
  13. i am getting "javax.crypto.IllegalBlockSizeException: last block incomplete in decryption" while decrypting image back

    ReplyDelete
    Replies
    1. Replace

      cipher = Cipher.getInstance("Blowfish");

      by

      cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");

      Delete
  14. C:\SujanaPrograms>java EncryptFile
    Exception in thread "main" java.lang.NoClassDefFoundError: EncryptFile (wrong na
    me: com/java/blowfish/EncryptFile)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$100(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

    I am getting this error while execution of code..what I have to do for this?

    ReplyDelete
    Replies
    1. Hi Sujana Pathuri,

      "javac EncryptFile.java" will compile the program without fail.
      However, inorder to run it, the class file (EncryptFile.class) should be present in the file path mentioned in the package directive in the program.
      i.e., "EncryptFile.class" should be placed in com/java/blowfish/

      After that run the program as "java com/java/blowfish/EncryptFile"

      Delete
  15. Is there a code to encrypt a folder??

    ReplyDelete
    Replies
    1. Hi,

      The Java Cryptography Extension (JCE) does not provide a way to do it, as such. You can do it recursively encrypting the files and sub folders in it or by taking a zip of the folder and encrypting. JCE provides facility to encrypt only file(s).

      Delete

Contact Form

Name

Email *

Message *