1
votes

I'm trying to encrypt/decrypt data using AES on Android and PHP side and recieving empty answer.

First, I generated symmetric key in Android:

public static  SecretKeySpec generateSymmetric() {

    // Set up secret key spec for 128-bit AES encryption and decryption
    SecretKeySpec sks = null;
    try {
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        sr.setSeed("any data used as random seed".getBytes());
        KeyGenerator kg = KeyGenerator.getInstance("AES");
        kg.init(128, sr);
        sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");

        System.out.println("AES KEY: " + sks);
    } catch (Exception e) {
        Log.e(TAG, "AES secret key spec error");
    }
    return sks;
}

Then i convert SecretKeySpec to Base64 string format:

public static String ConvertSymmetricKeyToString(SecretKeySpec key) {

    String symmetric_key = null;

    symmetric_key = Base64.encodeToString(key.getEncoded(), Base64.DEFAULT);
    return symmetric_key;
}

Call the functions:

    SecretKeySpec symmKey = generateSymmetric();


    newSymmetricKeyString = CreateEncryptedXml.ConvertSymmetricKeyToString(symmKey);

Then i encrypt data using SecretKeySpec:

    private static String encryptDataWithSymmetricKey (SecretKeySpec symmKey, String data) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {


    // encryption
    byte[] toBeCiphred = data.getBytes("UTF-8");
    String encryptedData = null;

    try {
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.ENCRYPT_MODE, symmKey);
        byte[] encodedBytes = c.doFinal(toBeCiphred);
        System.out.println("BYTE STRING (ASYMM): " + encodedBytes);
        encryptedData = Base64.encodeToString(encodedBytes, Base64.DEFAULT);

    } catch (Exception e) {
        Log.e(TAG, "AES encryption error");
        throw new RuntimeException(e);
    }


    return encryptedData;
}
    encryptedData = encryptDataWithSymmetricKey(symmKey, text);

Then i pack string secret AES key and encrypted data (encrypted with this AES key) in XML and make POST request to php server using okhttp. String secret key is encrypted using RSA.

On the server side I tried to decrypt data. I can decrypt (from RSA) secret AES key and get it's string representation. On client (Android) and server side (PHP) it's the same. But how can i decrypt data using this string AES key? I tried this (PHP):

   $encryptionMethod = "AES-128-CBC";  

  //$decryptedAESKey is an Android AES SecretKeySpec converted  to string
  //in Android the string key was base64_encoded, so i decode it
  $secretHash = base64_decode($decryptedAESKey);


 // Decrypt
  $decryptedMessage = openssl_decrypt(base64_decode($encryptedData),  $encryptionMethod, $secretHash);

  //Result
  echo "Encrypted: $encryptedData   ";
  echo " Decrypted: $decryptedMessage";

Result in php:

Encrypted:      s/00eZdv6sMq1hIgPUMMknb1w8d03t+R5KHn5FkHqhNJyDlBZlbm8t+t4RWh9tg/7LD9R2VbihGG
                                                                 Boz9ydMEszYGgTanE2TII+OOSFZIYgCU7ekKkRLax+F2yoMvSB52LDxQ9b9ZOTxy0Zn+hH6jbVdl
                                                               HVffbk+DJTJ1PVgeRfTaG4yC6cmXh5oFx7vDxM2u+8FWc3rNTt9zKUiu0FGLn3pWpA4wyCZfoCnA
                                                               rSJWrtaPLWxPEqipJCafTc1wRof9PqkDmIQJLOr84FpsnhH0JqjwXRmyDp5K8jKe+UzvE/B1B5Sj
                                                               QiTgK1Z2wPXzQClXimX2U9AQYc33FsYQMATHNw==
                                                                   Decrypted: 

What is wrong?

1
When asking for help a small example is helpful, this would include the key, short data, iv, mode and output.zaph
Welcome to Stack Overflow! General advice: Always use a fully qualified Cipher string. Cipher.getInstance("AES"); may result in different ciphers depending on the default security provider. It most likely results in "AES/ECB/PKCS5Padding", but it doesn't have to be. If it changes, you'll lose compatibility between different JVMs.Artjom B.
Never use ECB mode. It's deterministic and therefore not semantically secure. You should at the very least use a randomized mode like CBC or CTR. It is better to authenticate your ciphertexts so that attacks like a padding oracle attack are not possible. This can be done with authenticated modes like GCM or EAX, or with an encrypt-then-MAC scheme.Artjom B.

1 Answers

1
votes

When using CBC mode a block size (16-bytes for AES) iv (initialization vector) is required which is missing in the code. Also it is not clear what ENCRYPT_MODE is in the Android code.