views:

528

answers:

1

Hello there. So basically my program encrypt/decrypt string from text file which user choose. He can select one of five algorithms. The problem is when I create ciphertext with eg. AES and then save this ciphertext to text file and want to decrypt it to get the original string it does not work. Can someone point out where is the problem please ?

For example: If I encrypt String using AES: "Hello World !!" I get this ciphertext: "1za7slAXv2KZvDlVZlzu/A==" then I save it to .txt and use the second way for Decryption in order to get "Hello World !!" back. But the result is bad.

Is my approach good? Is there some better way?

Forget to add imports: And sorry for previous formatting.

import java.io.*;
import java.util.Scanner;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.KeyGenerator;

import java.security.spec.KeySpec;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.PBEKeySpec;

import javax.crypto.BadPaddingException;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.IllegalBlockSizeException;
import java.io.UnsupportedEncodingException;


public class sifrovaniRaw  {

Cipher sifr, desifr;



sifrovaniRaw(SecretKey klic, String algoritmus)
{
    try {
        sifr = Cipher.getInstance(algoritmus); 
        desifr = Cipher.getInstance(algoritmus);
        sifr.init(Cipher.ENCRYPT_MODE, klic);  
        desifr.init(Cipher.DECRYPT_MODE, klic);

    }
    catch (NoSuchPaddingException e) {
        System.out.println(" NoSuchPaddingException");
    }
    catch (NoSuchAlgorithmException e) {
        System.out.println(" NoSuchAlgorithmException");
    }
    catch (InvalidKeyException e) {
        System.out.println(" InvalidKeyException");
    }
}



sifrovaniRaw(String passph) {

    byte[] sul =
    {
        (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
        (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99

    };


    int iterace = 20;

    try {

        KeySpec klicSpecifikace = new PBEKeySpec(passph.toCharArray(), sul, iterace);
        SecretKey klic = SecretKeyFactory.getInstance("PBEWithMD5AndTripleDES").generateSecret(klicSpecifikace);

        sifr = Cipher.getInstance(klic.getAlgorithm());
        desifr = Cipher.getInstance(klic.getAlgorithm());


        AlgorithmParameterSpec parametry = new PBEParameterSpec(sul, iterace);

        sifr.init(Cipher.ENCRYPT_MODE, klic, parametry);
        desifr.init(Cipher.DECRYPT_MODE, klic, parametry);
    }
    catch (InvalidAlgorithmParameterException e) {
        System.out.println(" InvalidAlgorithmParameterException");
    }
    catch (InvalidKeySpecException e) {
        System.out.println(" InvalidKeySpecException");
    }
    catch (NoSuchPaddingException e) {
        System.out.println(" NoSuchPaddingException");
    }
    catch (NoSuchAlgorithmException e) {
        System.out.println(" NoSuchAlgorithmException");
    }
    catch (InvalidKeyException e) {
        System.out.println(" InvalidKeyException");
    }
}


public String encryption(String str) {
    try {

        byte[] utf8 = str.getBytes("UTF8");


        byte[] enco = sifr.doFinal(utf8);


        return new sun.misc.BASE64Encoder().encode(enco);

    } catch (BadPaddingException e) {
    } catch (IllegalBlockSizeException e) {
    } catch (UnsupportedEncodingException e) {
    } catch (IOException e) {
    }
    return null;
}



public String decryption(String str) {

    try {


        byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
        byte[] utf8 = desifr.doFinal(dec);


        return new String(utf8, "UTF8");

    } catch (BadPaddingException e) {
    } catch (IllegalBlockSizeException e) {
    } catch (UnsupportedEncodingException e) {
    } catch (IOException e) {
    }
    return null;
}





public static void testsecklic()
{


      System.out.println("Testing method using secret key");
      System.out.println("");

      try {
          System.out.println("Give a path:");
          System.out.println("-----");
          System.out.println("for UNIX eg: \"/home/user/text_to_encrypt/decrypt.txt\"");
          System.out.println("for NT Windows eg: \"C://FileIO//text.txt\"");
          System.out.println("------");
            Scanner scan = new Scanner(System.in);
            String filepath = scan.next();
            File file = new File(filepath);
            BufferedInputStream bin = null;

            FileInputStream fin = new FileInputStream(file);
            bin = new BufferedInputStream(fin);
            byte[] contents = new byte[1024];
            int bytesRead=0;
            String StringCont;

            while( (bytesRead = bin.read(contents)) != -1)
            {
                StringCont = new String(contents, 0, bytesRead);
                System.out.print(StringCont);


        SecretKey aesKlic    = KeyGenerator.getInstance("AES").generateKey();
        SecretKey desKlic       = KeyGenerator.getInstance("DES").generateKey();
        SecretKey desedeKlic    = KeyGenerator.getInstance("DESede").generateKey();
        SecretKey rc2Klic    = KeyGenerator.getInstance("RC2").generateKey();
        SecretKey blowfishKlic  = KeyGenerator.getInstance("Blowfish").generateKey();

        StringEncrypter aesEncrypt = new StringEncrypter(aesKlic, aesKlic.getAlgorithm());
        StringEncrypter desEncrypt = new StringEncrypter(desKlic, desKlic.getAlgorithm());
        StringEncrypter desedeEncrypt = new StringEncrypter(desedeKlic, desedeKlic.getAlgorithm());
        StringEncrypter rc2Encrypt = new StringEncrypter(rc2Klic, rc2Klic.getAlgorithm());
        StringEncrypter blowfishEncrypt = new StringEncrypter(blowfishKlic, blowfishKlic.getAlgorithm());


        String aesEncrypted       = aesEncrypt.encrypt(StringCont);
        String desEncrypted       = desEncrypt.encrypt(StringCont);
        String rc2Encrypted       = desedeEncrypt.encrypt(StringCont);
        String desedeEncrypted    = rc2Encrypt.encrypt(StringCont);
        String blowfishEncrypted  = blowfishEncrypt.encrypt(StringCont);


        String aesDecrypt       = aesEncrypt.decrypt(aesEncrypted);
        String desDecrypt       = desEncrypt.decrypt(desEncrypted);
        String rc2Decrypt       = rc2Encrypt.decrypt(desedeEncrypted);
        String desedeDecrypt    = desedeEncrypt.decrypt(rc2Encrypted);
        String blowfishDecrypt  = blowfishEncrypt.decrypt(blowfishEncrypted);



        //FIRST NON-WORKING WAY of decrypting.
        System.out.println("Do you want to encrypt[1] or decrypt[2] text ?");
        int sifDesif = scan.nextInt();

        if(sifDesif == 1)
        {
            System.out.println("What cypher do you want to choose?");
            System.out.println("AES[1], DES[2], rc2[3], blowfish[4], desede[5]");
            int vyber = scan.nextInt();

            switch(vyber)
            {
                case 1: System.out.println("encrypted : " + aesEncrypted); break;
                case 2: System.out.println("encrypted : " + desEncrypted); break;
                case 3: System.out.println("encrypted : " + rc2Encrypted); break;
                case 4: System.out.println("encrypted : " + blowfishEncrypted); break;
                case 5: System.out.println("encrypted : " + desedeEncrypted); break;
            }

        }
        else if(sifDesif == 2)
        {
            System.out.println("What cypher do you want to choose?");
            System.out.println("AES[1], DES[2], rc2[3], blowfish[4], desede[5]");
            int vyber = scan.nextInt();

            switch(vyber)
            {
                case 1:System.out.println("decrypted : " + aesDecrypt); break;
                case 2:System.out.println("decrypted : " + desDecrypt); break;
                case 3:System.out.println("decrypted : " + rc2Decrypt); break;
                case 4:System.out.println("decrypted : " + blowfishDecrypt); break;
                case 5:System.out.println("decrypted : " + desedeDecrypt); break;
            }
        }
        //SECOND WORKING WAY of decrypting.
        System.out.println("Algorith used:" + aesKlic.getAlgorithm());
        System.out.println("text  : " + StringCont);
        System.out.println("encryption : " + aesEncrypted);
        System.out.println("decryption text : " + aesDecrypt);
        System.out.println();



       }
    }
    catch (NoSuchAlgorithmException e)
    {
        System.out.println(" No such Algo");
    }
        catch(FileNotFoundException e)
    {
        System.out.println("File not found" + e);
    }
    catch(IOException ioe)
    {
        System.out.println("Exception while reading the file "+ ioe);
    }
}


public static void main(String[] args)
{
    testsecklic();
}

}

+1  A: 

Since you're generating the encryption keys every time, the program won't be able to decrypt a ciphertext that was created using a different encryption key. You'll need to find a way to persist the encryption key if you want to reuse it between runs of your program.

The following program is a smaller version of your original example except that it encrypts and decrypts the plaintext with each cipher. I didn't have access to the StringEncrypter class so I wrote a simple version:

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class EncTest {

    public static void main(String[] args) throws Exception {
        System.out.println("Testing method using secret key");

        String plaintext = "hello world";

        SecretKey aesKlic = KeyGenerator.getInstance("AES").generateKey();
        SecretKey desKlic = KeyGenerator.getInstance("DES").generateKey();
        SecretKey desedeKlic = KeyGenerator.getInstance("DESede").generateKey();
        SecretKey rc2Klic = KeyGenerator.getInstance("RC2").generateKey();
        SecretKey blowfishKlic = KeyGenerator.getInstance("Blowfish").generateKey();

        StringEncrypter[] ciphers = new StringEncrypter[] {
            new StringEncrypter(aesKlic, aesKlic.getAlgorithm()), 
            new StringEncrypter(desKlic, desKlic.getAlgorithm()), 
            new StringEncrypter(desedeKlic, desedeKlic.getAlgorithm()), 
            new StringEncrypter(rc2Klic, rc2Klic.getAlgorithm()), 
            new StringEncrypter(blowfishKlic, blowfishKlic.getAlgorithm())
        };

        byte[][] ciphertexts = new byte[ciphers.length][];

        int i = 0;
        for (StringEncrypter cipher : ciphers) {
            ciphertexts[i] = cipher.encrypt(plaintext);
            System.out.println(cipher.getAlgorithm() + " encrypted: " + hexEncode(ciphertexts[i]));
            i++;
        }

        System.out.println();

        i = 0;
        for (StringEncrypter cipher : ciphers) {
            System.out.println(cipher.getAlgorithm() + " decrypted: " + cipher.decrypt(ciphertexts[i]));
            i++;
        }
    }

    // Hex encoding lifted from commons-codec

    private static String hexEncode(byte [] input) {
        return new String(encodeHex(input));
    }

    private static char[] encodeHex(byte[] data) {

        int l = data.length;

           char[] out = new char[l << 1];

           // two characters form the hex value.
           for (int i = 0, j = 0; i < l; i++) {
               out[j++] = DIGITS[(0xF0 & data[i]) >>> 4 ];
               out[j++] = DIGITS[ 0x0F & data[i] ];
           }

           return out;
    }

    private static final char[] DIGITS = {
        '0', '1', '2', '3', '4', '5', '6', '7',
           '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    };

    private static class StringEncrypter {

        private final SecretKey key;
        private final String algorithm;

        public StringEncrypter(SecretKey key, String algorithm) {
            this.key = key;
            this.algorithm = algorithm;
        }

        public String getAlgorithm() {
            return algorithm;
        }

        public byte[] encrypt(String input) throws Exception {
            Cipher cipher = Cipher.getInstance(algorithm);
            cipher.init(Cipher.ENCRYPT_MODE, key);

            return cipher.doFinal(input.getBytes("UTF-8"));
        }

        public String decrypt(byte[] input) throws Exception {
            Cipher cipher = Cipher.getInstance(algorithm);
            cipher.init(Cipher.DECRYPT_MODE, key);

            return new String(cipher.doFinal(input));
        }

    }
}
Kevin
Thanks for answer. I just didn't realize that I got always new key :)But when I print out the key, I get something like this "javax.crypto.spec.SecretKeySpec@1708d;" and probably cant use it.I really need to be able store/restore the key but dont know how.I have some ideas but it would look propably bad.Could you provide some example please ?
dave91
You can get the raw key material using SecretKey#getEncoded(). You could then hex/base64 encode this and store it somewhere. However, this is quite insecure if you don't have a way to properly store your key material. I'd recommend using an appropriate PBE cipher instead
Kevin