1

I want to use an Encryption and Decryption algorithms common for Java, Android and Objective-C. I tried AES in java and android, both returns different output. Is there any common algorithm for Java, Android and Objective-C.

Here is the java code

import java.security.*;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.*;

public class AESencrp {

     private static final String ALGO = "AES";
    private static final byte[] keyValue =
        new byte[] { 'W', 'e', 'l', 'c', 'o', 'm', 'e','t', 'o', 'e', 'n','c', 'r', 'y', 'p', 't' };


public static String encrypt(String Data) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] encVal = c.doFinal(Data.getBytes());
        String encryptedValue = new BASE64Encoder().encode(encVal);
        return encryptedValue;
    }

    public static String decrypt(String encryptedData) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }
    private static Key generateKey() throws Exception {
        Key key = new SecretKeySpec(keyValue, ALGO);
        return key;
}
    public static void main(String[] args) throws Exception {

       // String password = "1";
       // String passwordEnc = AESencrp.encrypt(password);
        String passwordDec = AESencrp.decrypt("1");

      //  System.out.println("Plain Text : " + password);
       // System.out.println("Encrypted Text : " + passwordEnc);
        System.out.println("Decrypted Text : " + passwordDec);
    }
}

and here is my Android code

import java.security.SecureRandom;

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

import android.util.Base64;

public class EncodeDecodeAES {

    private final static String HEX = "0123456789ABCDEF";
    private final static int JELLY_BEAN_4_2 = 17;
    private final static byte[] key = { 'W', 'e', 'l', 'c', 'o', 'm', 'e','t', 'o', 'e', 'n','c', 'r', 'y', 'p', 't' };


    // static {
    // Security.addProvider(new BouncyCastleProvider());
    // }

    public static String encrypt(String seed, String cleartext) throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] result = encrypt(rawKey, cleartext.getBytes());
        String fromHex = toHex(result);
        String base64 = new String(Base64.encodeToString(fromHex.getBytes(), 0));
        return base64;
    }


    public static String decrypt(String seed, String encrypted) throws Exception {
        byte[] seedByte = seed.getBytes();
        System.arraycopy(seedByte, 0, key, 0, ((seedByte.length < 16) ? seedByte.length : 16));
        String base64 = new String(Base64.decode(encrypted, 0));
        byte[] rawKey = getRawKey(seedByte);
        byte[] enc = toByte(base64);
        byte[] result = decrypt(rawKey, enc);
        return new String(result);
    }


    public static byte[] encryptBytes(String seed, byte[] cleartext) throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] result = encrypt(rawKey, cleartext);
        return result;
    }


    public static byte[] decryptBytes(String seed, byte[] encrypted) throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] result = decrypt(rawKey, encrypted);
        return result;
    }


    private static byte[] getRawKey(byte[] seed) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES"); // , "SC");
        SecureRandom sr = null;
        if (android.os.Build.VERSION.SDK_INT >= JELLY_BEAN_4_2) {
            sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
        } else {
            sr = SecureRandom.getInstance("SHA1PRNG");
        }
        sr.setSeed(seed);
        try {
            kgen.init(256, sr);
            // kgen.init(128, sr);
        } catch (Exception e) {
            // Log.w(LOG, "This device doesn't suppor 256bits, trying 192bits.");
            try {
                kgen.init(192, sr);
            } catch (Exception e1) {
                // Log.w(LOG, "This device doesn't suppor 192bits, trying 128bits.");
                kgen.init(128, sr);
            }
        }
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        return raw;
    }


    private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES"); // /ECB/PKCS7Padding", "SC");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(clear);
        return encrypted;
    }


    private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES"); // /ECB/PKCS7Padding", "SC");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }


    public static String toHex(String txt) {
        return toHex(txt.getBytes());
    }


    public static String fromHex(String hex) {
        return new String(toByte(hex));
    }


    public static byte[] toByte(String hexString) {
        int len = hexString.length() / 2;
        byte[] result = new byte[len];
        for (int i = 0; i < len; i++)
            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
        return result;
    }


    public static String toHex(byte[] buf) {
        if (buf == null)
            return "";
        StringBuffer result = new StringBuffer(2 * buf.length);
        for (int i = 0; i < buf.length; i++) {
            appendHex(result, buf[i]);
        }
        return result.toString();
    }


    private static void appendHex(StringBuffer sb, byte b) {
        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
    }

}
Suresh Kumar
  • 2,014
  • 3
  • 19
  • 32
  • looks like in the android version you have an extra step. converting to HEXIDECIMAL between encrypting and base64 encoding. That's unnecessary and different than the pure java version – Garr Godfrey Mar 17 '15 at 06:29
  • First of all thanks for the reply. Java uses BASE64Encoder which is not supported in android. – Suresh Kumar Mar 17 '15 at 06:31
  • also, in the android version you don't appear to ever use your defined 'key', but I still think the toHex call will generate different result. – Garr Godfrey Mar 17 '15 at 06:34
  • The key is used in the decrypt() method. So is there any alternate for BASE64Endoder. – Suresh Kumar Mar 17 '15 at 06:38
  • but in the java version you use the keyValue in the encrypt. So you are encrypting with different keys. – Garr Godfrey Mar 17 '15 at 06:42
  • new BASE64Encoder().encode(encVal) and Base64.encodeToString(encval, 0) should do the same thing. – Garr Godfrey Mar 17 '15 at 06:44
  • I will try this and will be back. – Suresh Kumar Mar 17 '15 at 06:50
  • See http://stackoverflow.com/questions/2280375/how-can-i-make-my-aes-encryption-identical-between-java-and-objective-c-iphone to get identical encrytion with java and objective c. –  Mar 17 '15 at 07:05
  • Done. I used the same code of java in android and instead of BASE64Encoder I used Base64. It worked. Thanks to @GarrGodfrey. – Suresh Kumar Mar 17 '15 at 07:13

1 Answers1

0

I used the same Java code in Android and instead of BASE64Encoder I used Base64 and it works perfectly.

private static byte[] keyValue = new byte[]{ 'W', 'e', 'l', 'c', 'o', 'm', 'e','t', 'o', 'e', 'n','c', 'r', 'y', 'p', 't' };

private String seedWith16Chars = new String(keyValue);
private String textToEncrypt = "1";

private TextView seed;
private TextView text;
private TextView encryptedValue;
private TextView decryptedValue;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    seed = (TextView) findViewById(R.id.seedName);
    seed.setText(seedWith16Chars);

    text = (TextView) findViewById(R.id.textToEncrypt);
    text.setText(textToEncrypt);

    encryptedValue = (TextView) findViewById(R.id.encryptedText);
    decryptedValue = (TextView) findViewById(R.id.decryptedText);

    try {
        // This value was got when did run it from an 2.3.3 device a Galaxy SII running Android 4.0.4
        String encrypted = "";

        // Uncomment the line bellow and comment the line above to run it on an Android 4.1.2 or older.
        // String encrypted = EncodeDecodeAES.encrypt(seedWith16Chars, textToEncrypt);
        Log.e("Encrypt", encrypted);
        encrypted = encrypt(textToEncrypt);//EncodeDecodeAES.encrypt(seedWith16Chars, textToEncrypt);
        encryptedValue.setText("Encrypt "+encrypted);

        String decrypted = decrypt(encrypted);//EncodeDecodeAES.decrypt(seedWith16Chars, encrypted);
        decryptedValue.setText("Decrypt "+decrypted);
        Log.e("Decrypt", decrypted);
    } catch (Exception e) {
        Log.e("Exception", e.getLocalizedMessage());
    }

}

public static String encrypt(String Data) throws Exception {
    Key key = generateKey();
    Cipher c = Cipher.getInstance("AES");
    c.init(Cipher.ENCRYPT_MODE, key);
    byte[] encVal = c.doFinal(Data.getBytes());
    String encryptedValue = Base64.encodeToString(encVal, 0);
    return encryptedValue;
}

public static String decrypt(String encryptedData) throws Exception {
    Key key = generateKey();
    Cipher c = Cipher.getInstance("AES");
    c.init(Cipher.DECRYPT_MODE, key);
    byte[] decordedValue = Base64.decode(encryptedData, 0);
    byte[] decValue = c.doFinal(decordedValue);
    String decryptedValue = new String(decValue);
    return decryptedValue;
}
private static Key generateKey() throws Exception {
    Key key = new SecretKeySpec(keyValue, "AES");
    return key;
}
Suresh Kumar
  • 2,014
  • 3
  • 19
  • 32