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)

22 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. how would i seperate these programs for a client server model where i encrypt an image on one side and decrypt it on the other side

    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

Contact Form

Name

Email *

Message *