0

I have a problem with my code. I want to encrypt a message using a key made from passphrase. Then I want to send it (or use it somewhere, whatever) in String form (the encrypted one), and after that I want to decrypt it only by knowing the passphrase.

I wrote the code below, but I receive either IllegalBlockSizeException or BadPaddingException. I thought that badding would be took care by padding.

Here is my code:

Constructor and initialization:

public class AES_Cipher {

    private String keyString;
    private byte[] byteKey;
    private SecretKey key;
    Cipher c;

    public AES_Cipher(String keyString){
        this.keyString = keyString.toString();
    }

    public void init() throws InitializtionFailedException{
        try{
            c = Cipher.getInstance("AES/ECB/PKCS5Padding");
            byteKey = keyString.getBytes("UTF-8");
            MessageDigest sha = MessageDigest.getInstance("SHA-1");
            byteKey = sha.digest(byteKey);
            byteKey = Arrays.copyOf(byteKey, 16);
            key = new SecretKeySpec(byteKey, "AES");

        }catch(NoSuchAlgorithmException e){
            throw new InitializtionFailedException();
        }
}

Encrypt:

public String encrypt(String text) throws EncryptionException{
    try{
            c.init(Cipher.ENCRYPT_MODE, key);
            byte[] tmp = c.doFinal( text.getBytes("UTF-8")); 

            return new String(tmp, "UTF-8");
        }catch(IllegalBlockSizeException e){
            throw new EncryptionException();
        }
}

Decrypt:

public String decrypt(String text) throws DecryptionException{
        try{

        //byte[] decordedValue = new BASE64Decoder().decodeBuffer(text);
        // tried too use it but with poor outcome
        //c = Cipher.getInstance("AES/ECB/PKCS5Padding");
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] tmp1 = text.getBytes("UTF-8");
        //byte[] tmp = c.doFinal("aaaaaaaaaaaaaaaa".getBytes());
        //this returns BadPaddingException
        byte[] tmp = c.doFinal(text.getBytes());
        return new String(tmp, "UTF-8");

    }catch(IllegalBlockSizeException e){
    throw new DecryptionException();
    }
}

Of course there are some more exceptions.

Also, I would like to later use this code on android, and It doesn't need to be AES if there is some other Ciphers that are maybe less effective but less troublesome. But not simple XOR if that's not too much too ask.

Thank you in advance.

user2004685
  • 9,548
  • 5
  • 37
  • 54
MrHutnik
  • 118
  • 3
  • 9
  • This has nothing to do with AES. This would happen with every modern cipher. The issue is `new String(tmp, "UTF-8");` – Artjom B. Jan 30 '16 at 21:24
  • 1
    Possible duplicate of [IllegalBlockSizeException when trying to encrypt and decrypt a string with AES](http://stackoverflow.com/questions/30383736/illegalblocksizeexception-when-trying-to-encrypt-and-decrypt-a-string-with-aes) – Artjom B. Jan 30 '16 at 21:24
  • **Never use [ECB mode](http://crypto.stackexchange.com/q/14487/13022)**. It's deterministic and therefore not semantically secure. You should at the very least use a randomized mode like [CBC](http://crypto.stackexchange.com/q/22260/13022) or [CTR](http://crypto.stackexchange.com/a/2378/13022). It is better to authenticate your ciphertexts so that attacks like a [padding oracle attack](http://crypto.stackexchange.com/q/18185/13022) are not possible. This can be done with authenticated modes like GCM or EAX, or with an [encrypt-then-MAC](http://crypto.stackexchange.com/q/202/13022) scheme. – Artjom B. Jan 30 '16 at 21:24
  • @ArtjomB. Could you explain? How should I parse the String if not this way? And i thought if I use the same charset all the time it should work. – MrHutnik Jan 30 '16 at 23:04
  • Ok. So I menaged to handle it using BASE64Encoder and BASE64Decoder. Thanks for pointing me to the error :).Now I try to use it on android but I can't since there is no BASE64Encoder or Decoder. It only has BASE64 but it requires byte[] already, so it forces me to use String(tmp, "UTF-8") in order to convert encrypted byte array to String so I can send it further. And I don't see any exceptions in the logcat thus I am kind of blind. All I know it crashes on doFinal. Any thoughts that could help me? – MrHutnik Jan 31 '16 at 01:46
  • There's the `Base64#encodeToString()`, which should be equivalent to `new String(Base64.encode(tmp), "UTF-8")`. Base64 encoded characters are all printable and compatible with ASCII. – Artjom B. Jan 31 '16 at 09:57
  • Ok. I'm ussing it but decryption doesn't seem to work... My code: Encryption: `c.init(Cipher.ENCRYPT_MODE, key); byte[] textByte = text.getBytes("UTF-8"); byte[] tmp = c.doFinal(textByte); String return1 = Base64.encodeToString(tmp, Base64.DEFAULT);` and decryption: `.init(Cipher.ENCRYPT_MODE, key); byte[] textByte = Base64.decode(text, Base64.DEFAULT); byte[] tmp = c.doFinal(textByte); return new String(tmp, "UTF-8"); //Base64.encodeToString(tmp, Base64.DEFAULT);` – MrHutnik Jan 31 '16 at 20:33
  • Well, you're using `Cipher.ENCRYPT_MODE` twice. Please don't post extensive code into the comments. [edit] your question to include additional code. – Artjom B. Jan 31 '16 at 20:35
  • OK. Sorry for that. It seems to work, but I'll do some additional tests. Anyway I want to thank you very much. You're a genius, mate ;) – MrHutnik Jan 31 '16 at 21:16

1 Answers1

0

Ok. Seems to work now thanks to Artjom B.

Constructor and inicialization: public class AES_Cipher {

private String keyString;
private byte[] byteKey;
private SecretKey key;
Cipher c;

public AES_Cipher(String keyString){
    this.keyString = keyString.toString();
}

public void init() throws InitializtionFailedException{
    try{
        c = Cipher.getInstance("AES/ECB/PKCS5Padding");
        byteKey = keyString.getBytes("UTF-8");
        MessageDigest sha = MessageDigest.getInstance("SHA-1");
        byteKey = sha.digest(byteKey);
        byteKey = Arrays.copyOf(byteKey, 16);
        key = new SecretKeySpec(byteKey, "AES");

    }catch(NoSuchAlgorithmException e){
        throw new InitializtionFailedException();
    }
 }

Encryption:

 public String encrypt(String text) throws EncryptionException{
    try{
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] textByte = text.getBytes("UTF-8"); 
        byte[] tmp = c.doFinal(textByte);

        String return1 = Base64.encodeToString(tmp, Base64.DEFAULT);


        return return1;
}   // of course there is some exceptions catched down there

Decryption:

public String decrypt(String text) throws DecryptionException{
    try{

        c.init(Cipher.DECRYPT_MODE, key);
        byte[] textByte = Base64.decode(text, Base64.DEFAULT);

        byte[] tmp = c.doFinal(textByte);

        return new String(tmp, "UTF-8");

    }catch(IllegalBlockSizeException e){
        Log.d("Exception", "IllegalBlockSizeException");
        throw new DecryptionException();

    }  // wrote DecryptionException myself. 
       // also there is more Exceptions below
}
MrHutnik
  • 118
  • 3
  • 9