Zeeshan
Zeeshan

Reputation: 1655

Unable to decrypt AES encrypted string from Objective C

I want encrypt and decrypt in Android and IOS and PHP.

In android and in PHP using

when i encrypt and decrypt on android it works perfectly. but when I try to decrypt IOS or PHP encrypted String that is in Base64 or Hex2Binary. On android it decrypt string but first 16 character for IOS case and 19 character for PHP code it doest not decrypt showing other characters. I am pasting android code

            // Ignore this line this is for encoding
            //String input = "Congratulation, You've sucessfully decoded!";

            final byte[] iv = new byte[16];
            Arrays.fill(iv, (byte) 0x00);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

            // When I tried with this its gives "pad block corrupted" exception else work as above i told

            /*byte[] key = CommonUtilities.encryptionKey.getBytes("UTF-8");
            System.out.println(key.length);
            MessageDigest sha = MessageDigest.getInstance("SHA-256");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16); // use only first 128 bit
            System.out.println(key.length);
            System.out.println(new String(key,"UTF-8"));
            SecretKeySpec secretKey = new SecretKeySpec(key, "AES");*/

            // encryptionKey = "12345678901234561234567890123456"; Same in IOS and PHP
            SecretKeySpec skeySpec = new SecretKeySpec(CommonUtilities.encryptionKey.getBytes("UTF-8"), "AES");
            Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS7Padding");

            // Ignore these lines these are for encoding
            /*ecipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
            byte[] dstBuff = ecipher.doFinal(input.getBytes("UTF-8"));              
            System.out.println("encrypted: " + new String(dstBuff, "UTF-8")); 
            String enbin2hex = com.byte2hex(dstBuff);    
            String en = Base64.encodeToString(dstBuff, Base64.DEFAULT);*/    


            // this is Hex2Binay that IOS gives me to decrypt
            // Original Text: "hello shani how are you doing , Stuck in encryption ?"
            String strBin2Hex = "30BEF4AB063D0D72F91D8D11A7ADEE1B1EC58F67C4D9CC20F59FB56B8B23B7C665198CFF805897BD1AFB82E578AC82C6C18C0EA909E17540D0B95A81E8446168";



            ecipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
            byte[] de = ecipher.doFinal(com.hex2Byte(strBin2Hex));  

            //de = removeTrailingNulls(de);
            //int bytesDecryptedAfter = de.length;

            System.out.println("decrypted: " + new String(de, "UTF-8"));
            // Decrypted String "igohj&t`hnh"kkr&are you doing , Stuck in encryption ?"

Here you can see unable to decrypt full string "hello shani how " missing characters.

In IOS using

Any idea what i am doing wrong.

Thanks for you time

Upvotes: 0

Views: 2041

Answers (1)

Petro Korienev
Petro Korienev

Reputation: 4027

I see the issues:

  • Cipher mode (CBC in android code) isn't specified on iOS
  • Algorithm is specified explicitly on iOS (AES128), and not on Android
  • Algorithm does not accord to the key size on iOS 128/256.
  • Initial vector is different

So, instead of

CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                  keyPtr, kCCKeySizeAES256,
                                  "0000000000000000" /* initialization vector (optional) */,
                                  [self bytes], dataLength, /* input */
                                  buffer, bufferSize, /* output */
                                  &numBytesEncrypted);
 if (cryptStatus == kCCSuccess) {
     //the returned NSData takes ownership of the buffer and will free it on deallocation
     return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
 }

I would try

char iv[kCCBlockSizeAES128 + 1]; bzero(iv, sizeof(iv))
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding,
                                  keyPtr, kCCKeySizeAES128,
                                  iv,
                                  [self bytes], dataLength, /* input */
                                  buffer, bufferSize, /* output */
                                  &numBytesEncrypted);
 if (cryptStatus == kCCSuccess) {
     //the returned NSData takes ownership of the buffer and will free it on deallocation
     return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
 }

Ensure, that Android also uses AES128

Upvotes: 3

Related Questions