Results 1 to 9 of 9
  1. #1
    me.anchit is offline Member
    Join Date
    Jul 2011
    Posts
    26
    Rep Power
    0

    Post Java Encryption/Decryption - Loss of data

    hi, I m new to java encryption/decryption. I made a program to encrypt and decrypt files in smaller chunks so that large files can also be encrypted/decrypted. I tested it on a pdf(129kb) file and an mkv(594mb) file. Both of these files were corrupted when decrypted by the program. Then I tested it on a text file and found some text missing in the end(8 bytes in size). It is a password-based-encryption using "PBEWithMD5AndDES". The code is as follows :
    Java Code:
    package pack;
    
    import java.io.*;
    import java.security.MessageDigest;
    import java.security.spec.AlgorithmParameterSpec;
    import java.security.spec.KeySpec;
    import javax.crypto.*;
    import javax.crypto.spec.PBEKeySpec;
    import javax.crypto.spec.PBEParameterSpec;
    
    public class EncDec
    {
        public static void main(String args[])
        {
            EncDec ob=new EncDec();
            String ext="txt";
            ob.encrypt("oracle."+ext, "hello123");
            ob.decrypt("encfile.anc", "hello123","outp."+ext);
        }
        
        private void encrypt(String filepath, String password)
        {
            try
            {
                boolean flag=false;
                int maxsize=8*1024;
                File inputFile=new File(filepath);
                System.out.println("inputfile-encrypt"+inputFile.length());
                if((int)inputFile.length()<maxsize)
                {
                    flag=true;
                    maxsize=(int)inputFile.length();
                }
                System.out.println("maxsize-encrypt"+maxsize);
                byte[] chunk=new byte[maxsize];
                int endbytes=(int)inputFile.length()%maxsize;
                FileInputStream fis=new FileInputStream(inputFile);
                BufferedInputStream bis=new BufferedInputStream(fis, maxsize);
                String algo="PBEWithMD5AndDES";
                KeySpec ks=new PBEKeySpec(password.toCharArray());
                SecretKeyFactory skf=SecretKeyFactory.getInstance(algo);
                SecretKey key=skf.generateSecret(ks);
                MessageDigest md=MessageDigest.getInstance("MD5");
                md.update(password.getBytes());
                File saltfile=new File("salt.txt");
                FileOutputStream fsalt=new FileOutputStream(saltfile);
                byte[] salt=new byte[8];
                byte[] digest=md.digest();
                System.arraycopy(digest, 0, salt, 0, 8);
                AlgorithmParameterSpec aps=new PBEParameterSpec(salt, 20);
                Cipher cipher=Cipher.getInstance(algo);
                cipher.init(Cipher.ENCRYPT_MODE, key, aps);
                CipherInputStream cis=new CipherInputStream(bis, cipher);
                File file=new File("encfile.anc");
                if(file.exists())
                {
                    file.delete();
                }
                FileOutputStream fos=new FileOutputStream(file, true);
                BufferedOutputStream bos=new BufferedOutputStream(fos, maxsize);
                fsalt.write(salt);
                fsalt.close();
                int temp=(int)inputFile.length()/maxsize;
                if(!flag)
                {
                    for(int i=0;i<=temp;i++)
                    {
                        if(i==temp)
                        {
                            chunk=new byte[endbytes];
                            cis.read(chunk);
                            bos.write(chunk);
                            bos.flush();
                        }
                        else
                        {
                            cis.read(chunk);
                            bos.write(chunk);
                            bos.flush();
                        }
                    }
                }
                else
                {
                    cis.read(chunk);
                    bos.write(chunk);
                    bos.flush();
                }
                cis.close();
                bis.close();
                fis.close();
                bos.close();
                fos.close();
                System.out.println("outputfile-encrypt"+file.length());
            }
            catch(Exception e)
            {
                System.out.println(e.toString());
            }
        }
        
        private void decrypt(String filepath, String password, String outputfile)
        {
            try
            {
                boolean flag=false;
                int maxsize=8*1024;
                File inputFile=new File(filepath);
                FileInputStream fis=new FileInputStream(inputFile);
                BufferedInputStream bis=new BufferedInputStream(fis, maxsize);
                System.out.println("inputfile-decrypt"+inputFile.length());
                if((int)inputFile.length()<maxsize)
                {
                    flag=true;
                    maxsize=(int)inputFile.length();
                }
                System.out.println("maxsize-decrypt"+maxsize);
                byte[] salt=new byte[8];
                File saltfile=new File("salt.txt");
                FileInputStream fsalt=new FileInputStream(saltfile);
                fsalt.read(salt);
                fsalt.close();
                System.out.println("available-after-salt"+fis.available());
                byte[] chunk=new byte[maxsize];
                int endbytes=(int)(inputFile.length()%maxsize);
                System.out.println("endbytes"+endbytes);
                String algo="PBEWithMD5AndDES";
                KeySpec ks=new PBEKeySpec(password.toCharArray());
                SecretKeyFactory skf=SecretKeyFactory.getInstance(algo);
                SecretKey key=skf.generateSecret(ks);
                AlgorithmParameterSpec aps=new PBEParameterSpec(salt, 20);
                Cipher cipher=Cipher.getInstance(algo);
                cipher.init(Cipher.DECRYPT_MODE, key, aps);
                File file=new File(outputfile);
                if(file.exists())
                {
                    file.delete();
                }
                FileOutputStream fos=new FileOutputStream(file, true);
                BufferedOutputStream bos=new BufferedOutputStream(fos, maxsize);
                CipherOutputStream cos=new CipherOutputStream(bos, cipher);
                int temp=(int)inputFile.length()/maxsize;
                if(!flag)
                {
                    for(int i=0;i<=temp;i++)
                    {
                        if(i==temp)
                        {
                            chunk=new byte[endbytes];
                            bis.read(chunk);
                            cos.write(chunk);
                            cos.flush();
                        }
                        else
                        {
                            bis.read(chunk);
                            cos.write(chunk);
                            cos.flush();
                        }
                    }
                }
                else
                {
                    bis.read(chunk);
                    System.out.println("available-after-salt"+fis.available());
                    System.out.println(chunk.length);
                    cos.write(chunk);
                    cos.flush();
                }
                bis.close();
                fis.close();
                cos.close();
                fos.close();
                System.out.println("outputfile-decrypt"+file.length());
            }
            catch(Exception e)
            {
                System.out.println(e.toString());
            }
        }
    }
    Please help me with this.
    Thanks.
    Last edited by Norm; 07-31-2012 at 02:46 AM. Reason: added code tags

  2. #2
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    16,544
    Rep Power
    23

    Default Re: Java Encryption/Decryption - Loss of data

    When I execute the program, the encrypted file output contains 0s from byte 512 onwards.

    I changed the code to be easier for testing:
    Java Code:
       final static String FileIn = "EncDec.java";    // input file
       final static String EncFile = "EndDec.enc";  // encrypted file
       final static String DecFile = "EncDec_Dec.java";  // decrypted file
       final static String Password = "hello123";
    
        public static void main(String args[])      {
            EncDec ob=new EncDec();
            ob.encrypt(FileIn,  Password, EncFile);
            ob.decrypt(EncFile, Password, DecFile);
        }
        
        //---------------------------------------------------------
        private void encrypt(String filepath, String password, String decFile)         {
     ...
                File file=new File(decFile);
    If you don't understand my response, don't ignore it, ask a question.

  3. #3
    me.anchit is offline Member
    Join Date
    Jul 2011
    Posts
    26
    Rep Power
    0

    Default Re: Java Encryption/Decryption - Loss of data

    Ok...
    so you want me to do more testing of the program..?

  4. #4
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    16,544
    Rep Power
    23

    Default Re: Java Encryption/Decryption - Loss of data

    Did you look at the encrypted file that was created? Were the bytes at 512 all binary 0s?
    If you don't understand my response, don't ignore it, ask a question.

  5. #5
    sabre150 is offline Member
    Join Date
    Jul 2012
    Location
    Earth
    Posts
    75
    Rep Power
    0

    Default Re: Java Encryption/Decryption - Loss of data

    1) You need to read the Javadoc for InputStream.read(byte[] bytes). In both your encrypt and decrypt methods you make the assumption that it reads all the bytes you ask for; that is not necesserily the case.
    2) It does not make sense to open a file for 'append' when you have just made sure it does not exist.
    3) Your exception handling is very poor. Surely if you get an exception it is terminal and you can't carry on but you do.
    4) InputStream.available() does not do what you think it does.
    5) You don't need to use a BufferedInputStream especially one the length of your file. You will get almost no performance benefit and will rapidly run out of memory.
    6) When reading the salt from the file you should use DataInputStream.readFully(). You will get away with using InputStream.read(salt) most of the time but every now and again it will get up and bite you.

    There may be more wrong but that will do for the moment.
    Last edited by sabre150; 08-01-2012 at 04:15 PM.

  6. #6
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,189
    Rep Power
    19

    Default Re: Java Encryption/Decryption - Loss of data

    Sabre!!! Welcome!

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  7. #7
    me.anchit is offline Member
    Join Date
    Jul 2011
    Posts
    26
    Rep Power
    0

    Default Re: Java Encryption/Decryption - Loss of data

    @sabre150 : Thank you very much for reviewing my code. I am still in a learning phase so mistakes would probably be there.
    I made several changes to the code as you said. Through several tests I found that you are right about the read(byte[]) method, it is not reading all the bytes I expect it to read, instead it reads 512 bytes a time.
    Still, I have no clue how to make my program work the way I want it to.
    Plz help.
    Thank You.

  8. #8
    sabre150 is offline Member
    Join Date
    Jul 2012
    Location
    Earth
    Posts
    75
    Rep Power
    0

    Default Re: Java Encryption/Decryption - Loss of data

    Quote Originally Posted by DarrylBurke View Post
    Sabre!!! Welcome!

    db
    Thanks Darryl and Hi. I'm not sure I will make regular visits here but we will see.

    Sabre

  9. #9
    sabre150 is offline Member
    Join Date
    Jul 2012
    Location
    Earth
    Posts
    75
    Rep Power
    0

    Default Re: Java Encryption/Decryption - Loss of data

    Quote Originally Posted by me.anchit View Post
    @sabre150 :
    Plz help.
    Thank You.
    If you know how to copy a file using streams then it is very very easy to adapt that code to encrypting or decrypting the the file ( the same basic code can be used for both encrypt and decrypt just by changing the Cipher initialisation). The basic steps are

    1) Setup the Cipher to encrypt mode or decrypt mode.
    2) create a buffer to work with. A byte array of about 4K is normally adequate.
    3) create a FileInputStream for the input file.
    4) create a FileOutputStream for the output file.
    5) wrap the FileInputStream with a CipherInputStream initialised with the Cipher
    6) Loop reading bytes from the CipherInputStream into the buffer and writing the buffer (make sure you only write the number actually read) to the FileOutputStream until you reach the end of file.
    7 Close the FileOutputStream and the CipherInputStream.

    Note - in its basic form steps 2 to 7 require only about 8 lines of code - 3 to create the streams, 2 to close the streams, 1 to define the buffer and 2 to do the actual read and write. To create good code you will need a few more line so make sure the streams are closed even in the event of an IO error. The same code, and I mean the same and not just a copy, can be use for both encryption and decryption with a single boolean parameter to indicate which.

Similar Threads

  1. Encryption & Decryption
    By raj.mscking@gmail.com in forum New To Java
    Replies: 1
    Last Post: 02-01-2012, 02:21 PM
  2. Blue Pelican Java: Help with Encryption/Decryption
    By ohwegg1 in forum New To Java
    Replies: 0
    Last Post: 01-29-2012, 12:48 AM
  3. Encryption and Decryption
    By jatinkansagara in forum Advanced Java
    Replies: 7
    Last Post: 06-27-2011, 03:08 PM
  4. PGP Encryption&Decryption
    By Deepa in forum New To Java
    Replies: 2
    Last Post: 07-07-2009, 06:22 AM
  5. Encryption/Decryption Through AOP
    By SirRawlins in forum Advanced Java
    Replies: 0
    Last Post: 12-19-2007, 03:22 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •