The D Merged
The D Merged

Reputation: 680

Encryption class working in java but not in android, why? What else can i do?

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

Upvotes: 1

Views: 4022

Answers (4)

Android_coder
Android_coder

Reputation: 9993

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");
}

Upvotes: 4

Dr. Xperience
Dr. Xperience

Reputation: 495

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

Upvotes: 1

jarnbjo
jarnbjo

Reputation: 34313

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");

Upvotes: 2

Rene M.
Rene M.

Reputation: 2690

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.

Upvotes: 2

Related Questions