Hello. I submitted this post a little while ago where I had problems with decrypting what I encrypted. Now my problem is that when I encrypt something and then decrypt it, the decryption works with txt files, but when I try to decrypt microsoft documents, then they will not open. I did a couple of tests, and it seems like any more advanced file will get corrupted (pdf, docx, ppt, etc.) Here is my new code for the encryption

package sec;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import java.math.BigInteger;
import java.security.*;


public class Cryption {

    private Cipher c;
    private SecretKey k;
    private byte[] iv = {0,0,0,0,0,0,0,0};
    public Cryption(){
        try {
            c = Cipher.getInstance("DES/CBC/PKCS5Padding");
            KeyGenerator kg = KeyGenerator.getInstance("DES");
            k = kg.generateKey();
            System.out.println("k = " + k);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public String encrypt(String dec) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException{
            KeyGenerator kg = KeyGenerator.getInstance("DES");
            k = kg.generateKey();
            IvParameterSpec ivspec = new IvParameterSpec (iv);
            c.init(Cipher.ENCRYPT_MODE, k, ivspec);
            String enc = new String(c.doFinal(dec.getBytes()));
            return enc;

    }

    public String decrypt(String enc) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException{
            IvParameterSpec ivspec = new IvParameterSpec (iv);
            //System.out.println("k = " + k);
            c.init(Cipher.DECRYPT_MODE, k, ivspec);
            String dec = new String(c.doFinal(enc.getBytes()));
            return dec;
    }

    public String saveKey(){
        byte[] enc = k.getEncoded();
        String save = new BigInteger(1, enc).toString(16);

        return save;
    }
    public void loadKey(String s){
        byte[] enc = new BigInteger(s, 16).toByteArray();
        k = new SecretKeySpec(enc, "DES");
    }

}

How can I fix this problem?

Thanks for the help.

Recommended Answers

All 6 Replies

I already told you in your previous topic that you cannot use a String to hold a byte array and expect to get it back unchanged.

byte[] in = ....
String s = new String(in);
byte[] out = s.getBytes();
// depending on your default character set, out will NOT be the same as in, 
// particularly for byte values >= 0x7f

Then can you gove me any suggestions on how to read and write both strings and bytes from one inputStream. The way I have it set up is that I have a separate file which contains the key and the extension for the type of document it was (.txt, .docx, etc.).

I also have another problem, where I keep getting an error saying that the key length is incorrect. Is this the same problem with the bytes not being the same, or is it some other problem?

Thanks for the help

Forget the Strings. Encryption/decryption just treats everything as bytes, so the last thing you want is Java doing character "interpretation" of those bytes into/out of some random character set. Just read the input file as an array of bytes, encode that to an array of bytes and write those bytes to the output file along with/just like the key (array of bytes). Ditto for decryption.
The file extension is a special case if you assume it is pure ASCII (under 0x7f) so you can convert that String to array of bytes for writing to file, and vice-versa.

I have managed to get one of the larger text files I was having problems with encrypted and decrypted successfully, but my problem still exists with the pdf and the microsoft documents.

Here is my new code

package sec;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import java.math.BigInteger;
import java.security.*;


public class Cryption {

    private Cipher c;
    private SecretKey k;
    private byte[] iv = {0,0,0,0,0,0,0,0/*,0,0,0,0,0,0,0,0*/};
    public Cryption(){
        try {
            c = Cipher.getInstance("DES/CBC/PKCS5Padding");
            KeyGenerator kg = KeyGenerator.getInstance("DES");
            k = kg.generateKey();
            System.out.println("k = " + k);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public byte[] encrypt(String dec) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException{
            KeyGenerator kg = KeyGenerator.getInstance("DES");

            k = /*new SecretKeySpec("00000000".getBytes(), "DES");*/kg.generateKey();
            IvParameterSpec ivspec = new IvParameterSpec (iv);
            c.init(Cipher.ENCRYPT_MODE, k, ivspec);
            byte[] enc = c.doFinal(dec.getBytes());
            return enc;

    }

    public String decrypt(byte[] enc) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException{
            IvParameterSpec ivspec = new IvParameterSpec (iv);
            //System.out.println("k = " + k);
            c.init(Cipher.DECRYPT_MODE, k, ivspec);
            String dec = new String(c.doFinal(enc));
            return dec;
    }

    public byte[] saveKey(){
        byte[] enc = k.getEncoded();
        //String save = new BigInteger(1, enc).toString(16);

        return enc;
    }
    public void loadKey(byte[] key){
        //byte[] enc = new BigInteger(key, 16).toByteArray();
        k = new SecretKeySpec(key, "DES");
    }

}

and Here is how I solved the key output and the string output

Reading:

byte[] key;
            String ext;
            try {
                FileInputStream in = new FileInputStream(new File(from.getParent() + "\\prop" + from.getName()));
                byte[] extension = new byte[in.read()];
                in.read(extension);
                ext = new String (extension);
                System.out.println(ext);
                key = new byte[in.available()];
                in.read(key);
                //System.out.println(key);

                //System.out.println(ext);
                in.close();             
                FileInputStream fin = new FileInputStream(from);
                try {
                    byte[] bytes = new byte[fin.available()];
                    fin.read(bytes);
                    Instances.c.loadKey(key);
                    String dec = Instances.c.decrypt(bytes);
                    //System.out.println(dec);
                    fin.close();

                    to = new File(to.getAbsoluteFile() + "\\" + from.getName().substring(0, from.getName().indexOf('.')-1) + "." + ext);
                    to.createNewFile();
                    FileWriter fw = new FileWriter(to);

                    fw.write(dec);
                    fw.close();
                    JOptionPane.showMessageDialog(null, "File has been copied");

                    from.delete();
                    new File(from.getParent() + "\\prop" + from.getName()).delete();
                } catch (IOException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }



            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(from.getParent() + "\\prop" + from.getName());

Writing:

try {
                System.out.println("Submitting");
                //Calendar c = Calendar.getInstance();
                String timeStamp = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(Calendar.getInstance().getTime())  + ".ppc";
                //String name = c.YEAR + "_" + c.MONTH + "_" + c.DAY_OF_MONTH + "_" + c.getTime().getHours() + "-" + c.getTime().getMinutes() + "-" + c.getTime().getSeconds() + ".pnc";
                FileInputStream in = new FileInputStream(copyFile);
                File outF = new File(Instances.drives[pComboBox.getSelectedIndex()] + timeStamp);
                FileOutputStream fw = new FileOutputStream(outF);
                outF.mkdirs();


                byte [] bytes = new byte [in.available()];
                in.read(bytes);
                byte[] enc = null;
                try {
                    enc = Instances.c.encrypt(new String (bytes));
                } catch (NoSuchAlgorithmException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                fw.write(enc);

                in.close();
                fw.close();

                String dr = Instances.drives[pComboBox.getSelectedIndex()];

                Runtime.getRuntime().exec("attrib +H " + dr + "prop" + timeStamp);

                FileOutputStream f = new FileOutputStream(dr + "prop" + timeStamp);
                int end = copyFile.getName().indexOf('.', copyFile.getName().length() - 6) + 1;
                String ext = copyFile.getName().substring(end);
                f.write(ext.length());
                f.write(ext.getBytes());

                f.write(Instances.c.saveKey());



                f.close();
                System.out.println("Drive Selected: " + dr);
                JOptionPane.showMessageDialog(null, "The File has Been copied");
            } catch (IOException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

Thanks for the help.

You are still passing the data to encrypt as a String. That will be corrupted for anything other than ASCII text. Get rid of the |Strings and just work with byte[]

Thanks for the help. I didn't realize that it mattered that I passed the original in a a string. I fixed it by changing the input for the encrypt and the output for the decrypt to bytes, and writing them to files like that. Thanks for the help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.