1

I did a simple encrypt/decrypt string class in java and tested it. It workes fine, now im trying to use it in an android device to encrypt a string, send it to my server and there decrypt it. All using the same custom class. Why is this not working? Is it simply not supported? what else can i do to easily encrypt/decrypt a string for this purpose? Base64 is not accepted:)

package crypto;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;


public class Crypto {
    public static byte[] encrypt(String message) throws Exception
    {
        String symmetricKey = "25Ae1f1711%z1 )1";
        SecretKeySpec aesKey = new SecretKeySpec(symmetricKey.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(message.getBytes());
    }
    public static String decrypt(byte[] encryptedMessage) throws Exception
    {
        String symmetricKey = "25Ae1f1711%z1 )1";
        SecretKeySpec aesKey = new SecretKeySpec(symmetricKey.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
        cipher.init(Cipher.DECRYPT_MODE, key);
        return new String(cipher.doFinal(encryptedMessage));
    }
}

In logcat i can see the following exception pop up: java.security.NoSuchProviderException: Provider not avalible: SunJCE

I deleted the specified provider "SunJCE" from the line.

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");

i found the solution to this over here

now i get this error at the serverside instead:

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:317)
    at javax.crypto.Cipher.doFinal(Cipher.java:1813)
    at crypto.Crypto.decrypt(Crypto.java:20)
    at io.network.UDPServer.run(UDPServer.java:37

tried with BC but i still have the same error

Community
  • 1
  • 1
The D Merged
  • 680
  • 9
  • 17
  • 1
    http://stackoverflow.com/questions/17079579/aes-algo-decryption-issue/17080884#17080884. check this might help. – Raghunandan Jul 29 '13 at 13:39
  • 3
    What do you mean by not working? –  Jul 29 '13 at 13:39
  • 1
    The encryption methods available on a VM are version specific. I suggest you get a list of encryptions supported on your system and use one of those. – Peter Lawrey Jul 29 '13 at 13:39
  • it throws an error i guess, its working fine to send the strings and use the encryption class in pure java, tested it. But when i use the method befor i send and after i recieve something fails:/ – The D Merged Jul 29 '13 at 13:43
  • 3
    `getInstance` of `"SunJCE"` is unlikely to be available on Android. – Joop Eggen Jul 29 '13 at 13:51
  • 1
    `String.getBytes()` is a no-no. Always specify a charset; you can't go wrong with "UTF-8". Similarly, never use the default charset for that String constructor. – President James K. Polk Jul 30 '13 at 01:19
  • 1
    `"25Ae1f1711%z1 )1"` is not a salt; it is a secret key. Now that it's not secret anymore, your encryption is useless. Please see this: http://blogs.msdn.com/b/ericlippert/archive/2011/09/27/keep-it-secret-keep-it-safe.aspx – ntoskrnl Jul 30 '13 at 17:22
  • Thanks, i know that but ill make an edit to dont confuse others:) – The D Merged Jul 30 '13 at 20:59

4 Answers4

4

Try this code: Call encrypt method like this: encrypt_text = Encrypt(Text,"avs3qt");

Encrypt function definition:

String Encrypt(String text, String key) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    byte[] keyBytes = new byte[16];
    byte[] b = key.getBytes("UTF-8");
    int len = b.length;
    if (len > keyBytes.length)
        len = keyBytes.length;
    System.arraycopy(b, 0, keyBytes, 0, len);
    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
    IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

    byte[] results = cipher.doFinal(text.getBytes("UTF-8"));
    BASE64Decoder encoder = new BASE64Decoder();
    return encoder.encodeBytes(results);
}

call Decrypt method like this:

decrypt_text = Decrypt(Text, "avs3qt");

Function definition:

String Decrypt(String text, String key) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    byte[] keyBytes = new byte[16];
    byte[] b = key.getBytes("UTF-8");
    int len = b.length;
    if (len > keyBytes.length)
        len = keyBytes.length;
    System.arraycopy(b, 0, keyBytes, 0, len);
    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
    IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
    cipher.init(Cipher.DECRYPT_MODE, keySpec,ivSpec);

    BASE64Decoder decoder = new BASE64Decoder();
    byte[] results = cipher.doFinal(decoder.decode(text));
    return new String(results, "UTF-8");
}
Seraphim's
  • 12,559
  • 20
  • 88
  • 129
Android_coder
  • 9,953
  • 3
  • 17
  • 23
2

It depends on the security provider. On Android and in JVM are different defaults and not all Sun/Oracle Algorithm exist on android, too.

I had nearly the same problem and was solving it by switching to bounce castle (BC). It exist on both sides and are working in exactly the same metter.

I'm using "RSA/ECB/PKCS1Padding" as Transformation on both sides. And its working.

Rene M.
  • 2,660
  • 15
  • 24
2

Your code won't run on any Java VM except Oracle's. The reason is that you request a specific cryptography provider called "SunJCE", which is the reference implementation of the JCE API from Oracle (previously Sun).

Just change your code to accept any provider capable of handling the requested algorithm:

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

jarnbjo
  • 33,923
  • 7
  • 70
  • 94
1

Yo Brother, I have just made an App on android which uses encryption

Have a look at this following question

Java 256-bit AES Password-Based Encryption

Check out the reply given by wufoo (the one having 14 pts)

Just omit use of import org.apache.commons.codec.binary.Hex; and its methods (As the method used in by Hex class are from new version of the apache api and android have built in apache of older version, Plus in android native api is given preference over external library/api )

and download plus reference the org.apache.common from this link http://commons.apache.org/proper/commons-codec/

I hope it helps

Devel

Community
  • 1
  • 1
Dr. Xperience
  • 475
  • 1
  • 5
  • 18