1 Replies - 285 Views - Last Post: 06 October 2013 - 02:08 AM Rate Topic: -----

#1 supratroopa  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 08-October 12

Cannot encrypt .jpg files in Java

Posted 05 October 2013 - 08:09 PM

Hi there,
I'm writing two programs; one that encrypts a file given in the first argument, with a ASCII seed given in the second argument, and another that decrypts the encrypted file. The algorithm uses AES-128 in CBC stream cipher mode. The file is read into a buffer, a SHA-1 hash is produced and attached to the plaintext, and then encrypted. The seed is also produced by SHA-1. The program that decrypts (using the same seed) separates the message from the digest and compares the digest with a locally produced hash. So far, the two programs work perfectly for a .txt file, but if I try to encrypt/decrypt a .jpg or .png file, all that is left of the original image is a small part of the top - the rest is just random colors. .zip files come out corrupted.

My code is pretty large, my apologies.

encrypt:
public class secureFile 
{
private static SecretKeySpec sec_key_spec;
private static Cipher sec_cipher;
private static final int SIZE_LIMIT = 1024;
private static final int SHA1_SIZE = 20;


// encryption function
public static byte[] encrypt(byte[] plaintext) throws Exception
{
    byte[] encrypted = null;
    byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    IvParameterSpec ivspec = new IvParameterSpec(iv);
    try {
        //set cipher object to encrypt mode
        sec_cipher.init(Cipher.ENCRYPT_MODE, sec_key_spec, ivspec);

        //create ciphertext
        encrypted = sec_cipher.doFinal(plaintext);
    }
    catch(Exception e) {
        System.out.println(e);
    }
    return encrypted;
}


//creates SHA-1 message digest
public static byte[] createDigest(byte[] message) throws Exception
{
    byte[] hash = null;
    try{
        //create message digest object
        MessageDigest sha1 = MessageDigest.getInstance("SHA1");

        //make message digest
        hash = sha1.digest(message);    
    }
    catch(NoSuchAlgorithmException nsae) {
        System.out.println(nsae);
    }
    return hash;
}


public static void main (String args[]) throws Exception 
{   
    byte[] key;
    byte[] key128;
    FileInputStream mFile;
    FileOutputStream cFile;
    byte[] ciphertext;
    byte[] plaintext;
    byte[] sha1_hash;   
    byte[] message;
    String cFilename;
    int file_size;

    try {
        //gets filenames and fileinput
        String[] mFilename = args[0].split("\\.(?=[^\\.]+$)");
        cFilename = mFilename[0] + "EN." + mFilename[1];
        mFile = new FileInputStream(mFilename[0] + "." + mFilename[1]);

        //limits buffer size to 1024
        file_size = mFile.available();
        if (file_size > SIZE_LIMIT) {
            file_size = SIZE_LIMIT;
        }

        //reads message file in buffer
        message = new byte[file_size];
        mFile.read(message);
        mFile.close();

        //creates sha1 digest from message
        sha1_hash = createDigest(message);

        //combines message and digest
        plaintext = new byte[file_size + SHA1_SIZE];
        for (int i = 0; i < file_size; i++) {
            plaintext[i] = message[i];
        }
        for (int j = 0; j < SHA1_SIZE; j++) {
            plaintext[file_size + j] = sha1_hash[j];
        }

        //generates key
        key = createDigest(args[1].getBytes("us-ascii"));
        key128 = Arrays.copyOfRange(key, 0, 16);
        sec_key_spec = new SecretKeySpec(key128, "AES");

        //enciphers the plaintext
        sec_cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        ciphertext = encrypt(plaintext);

        //copies ciphertext to file
        cFile = new FileOutputStream(cFilename);
        cFile.write(ciphertext);
        cFile.close();
    }
    catch (Exception e) {
        System.out.println(e);
    }
  }
}



decrypt:
import java.io.*;
import java.util.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class decryptFile
{
private static SecretKeySpec sec_key_spec = null;
private static Cipher sec_cipher = null;
private static final int SHA1_SIZE = 20;


//decryption function
public static byte[] decrypt(byte[] ciphertext) throws Exception{
    byte[] decrypted = null;
    byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    IvParameterSpec ivspec = new IvParameterSpec(iv);
    try{
        //set cipher to decrypt mode
        sec_cipher.init(Cipher.DECRYPT_MODE, sec_key_spec, ivspec);

        //do decryption
        decrypted = sec_cipher.doFinal(ciphertext);
    }
    catch (BadPaddingException B)/>
    {
        sec_cipher.init(Cipher.ENCRYPT_MODE, sec_key_spec, ivspec);
        decrypted = sec_cipher.doFinal(ciphertext);
    }
    catch(Exception e){
        System.out.println(e);
    }

    return decrypted;
}


//creates digest
public static byte[] createDigest(byte[] message) throws Exception
{
    byte[] hash = null;
    try{
        //create message digest object
        MessageDigest sha1 = MessageDigest.getInstance("SHA1");

        //make message digest
        hash = sha1.digest(message);    
    }
    catch(NoSuchAlgorithmException nsae) {
        System.out.println(nsae);
    }
    return hash;
}


//compares two digests
public static String compareDigests(byte[] digest, byte[] local_digest)
{
    for (int i = 0; i < SHA1_SIZE; i++)
    {
        if (digest[i] != local_digest[i]) {
            return "Digests don't match; your file may have been tampered with.";
        }
    }
    return "Digests match!";
}


public static void main (String args[]) 
{
    FileInputStream cFile;
    FileOutputStream mFile;
    byte[] key;
    byte[] key128;
    byte[] ciphertext;
    byte[] decrypted;
    byte[] message;
    byte[] digest;
    byte[] local_digest;
    byte[] local_digest2;
    String mFilename;
    int file_size;

    try {
        //obtains filenames
        String[] cFilename = args[0].split("\\.(?=[^\\.]+$)");
        mFilename = cFilename[0] + "DE." + cFilename[1];
        cFile = new FileInputStream(cFilename[0] + "." + cFilename[1]);

        //reads ciphertext file
        cFile = new FileInputStream(cFilename[0] + "." + cFilename[1]);
        ciphertext = new byte[cFile.available()];
        cFile.read(ciphertext);
        cFile.close();

        //generates key
        key = createDigest(args[1].getBytes("us-ascii"));
        key128 = Arrays.copyOfRange(key, 0, 16);
        sec_key_spec = new SecretKeySpec(key128, "AES");

        //deciphers the plaintext
        sec_cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        decrypted = decrypt(ciphertext);

        //splits plaintext between message and digest
        file_size = decrypted.length;
        message = Arrays.copyOfRange(decrypted, 0, (file_size - SHA1_SIZE));
        digest = Arrays.copyOfRange(decrypted, (file_size - SHA1_SIZE), file_size);

        //compares digests
        local_digest = createDigest(message);
        System.out.println(compareDigests(digest, local_digest));

        //copies message to file
        mFile = new FileOutputStream(mFilename);
        mFile.write(message);
        mFile.close();
    }
    catch (Exception e) {
        System.out.println(e);
    }
 }
}



I very much appreciate any help you can give me. Thank you!

Is This A Good Question/Topic? 0
  • +

Replies To: Cannot encrypt .jpg files in Java

#2 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2657
  • View blog
  • Posts: 11,208
  • Joined: 20-September 08

Re: Cannot encrypt .jpg files in Java

Posted 06 October 2013 - 02:08 AM

Quote

but if I try to encrypt/decrypt a .jpg or .png file, all that is left of the original image is a small part of the top - the rest is just random colors. .zip files come out corrupted.


Because you tell it to treat only the first 1KiB of the file:

Quote

            //limits buffer size to 1024
            file_size = mFile.available();

            if (file_size > SIZE_LIMIT) {
                file_size = SIZE_LIMIT;
            }



Of course, reading the whole lot into a buffer sized at the file size at once is not a practical solution

btw, the code above is also wrong in itself. You can't use available like that. Look at the API docs carefully to see why. If the code above were legitimate (it isn't of course), what you'd want is File.length()

This post has been edited by g00se: 06 October 2013 - 02:12 AM
Reason for edit:: Clarification

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1