Search code examples
javaencryption3des

3des encrypting/decrypting of file java


I have a problem to read the file (for example *.zip) and encrypt it with 3DES, using secretKey which one generated from name of encrypted file. Then I need to decrypt this file, and write it on HDD. I tried to resolve thhis problem, but stuck when was decrypting file.

Here is code of encryptor

public class Encryptor {
    private static String inputFilePath = "D:/1.txt";
    public static void main(String[] args) {
        FileOutputStream fos = null;
        File file = new File(inputFilePath);
        String keyString = "140405PX_0.$88";
        String algorithm = "DESede";
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] fileByteArray = new byte[fileInputStream.available()];
            fileInputStream.read(fileByteArray);
            for (byte b : fileByteArray) {
            System.out.println(b);
            }
            SecretKey secretKey = getKey(keyString);
            Cipher cipher = Cipher.getInstance(algorithm);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream
                    (new CipherOutputStream
                            (new FileOutputStream
                                    ("D:/Secret.file"), cipher));
            objectOutputStream.writeObject(fileByteArray);
            objectOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static SecretKey getKey(String message) throws Exception {
        String messageToUpperCase = message.toUpperCase();
        byte[] digestOfPassword = messageToUpperCase.getBytes();
        byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
        SecretKey key = new SecretKeySpec(keyBytes, "DESede");
        return key;
    }
}

And here is code of decryptor

public class Decryptor {
    public static void main(String[] args) {
        try {
            File inputFileNAme = new File("d:/Secret.file");
            FileInputStream fileInputStream = new FileInputStream(inputFileNAme);
            FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath);
            SecretKey secretKey = getKey(keyString);
            Cipher cipher = Cipher.getInstance(algorithm);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            ObjectInputStream objectInputStream = new ObjectInputStream
                    (new CipherInputStream(fileInputStream, cipher));
            System.out.println(objectInputStream.available());
            while (objectInputStream.available() != 0) {
                fileOutputStream.write((Integer) objectInputStream.readObject());
                System.out.println(objectInputStream.readObject());
            }
            fileOutputStream.flush();
            fileOutputStream.close();
            fileInputStream.close();
            objectInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static SecretKey getKey(String message) throws Exception {
        String messageToUpperCase = message.toUpperCase();
        byte[] digestOfPassword = messageToUpperCase.getBytes();
        byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
        SecretKey key = new SecretKeySpec(keyBytes, "DESede");
        return key;
    }
}

When i try to decrypt my file, i dont get anything in output file.
I tryed make debug, and saw, that objectInputStream.available() always contains 0.
Please tell me, how can I resolve this problem, and why it happens.


Solution

    1. The usage

      byte[] fileByteArray = new byte[fileInputStream.available()];
      

      is specifically warned against in the Javadoc: " It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream."

      Files should be processed a record or a buffer at a time.

    2. The line:

      fileInputStream.read(fileByteArray);
      

      isn't guaranteed to fill the buffer. You have to check the return value: for -1, meaning end of file, or > 0, meaning the number of bytes that were actually transferred. See the Javadoc.

    3. Similarly

      while (objectInputStream.available() != 0) {
      

      is not a valid test for end of stream. You should call readObject() until it throws EOFException.