0

I have problem converting .NET C# AES 128 Encryption to iOS (iPhone). Everything generated correctly except the last block. The final call to xfrm.TransformFinalBlock generate differently than what I got from iOS code (using CCCryptorFinal). I am using the same parameter for BlockSize, Key and IV. What else am I missing? Thank you.

Obj-C

CCCryptorStatus ccStatus = kCCSuccess;


CCCryptorRef thisEncipher = NULL;

// Create and Initialize the crypto reference.
ccStatus = CCCryptorCreate(kCCEncrypt, 
                           kCCAlgorithmAES128, 
                           kCCOptionPKCS7Padding, 
                           szKey,
                           kCCKeySizeAES128, 
                           iv, 
                           &thisEncipher
                           );

// Calculate byte block alignment for all calls through to and including final.
int bufferPtrSize = CCCryptorGetOutputLength(thisEncipher, InputLength, true);

unsigned char *szResult = (unsigned char *)malloc(bufferPtrSize+1);

memset(szResult, 0x00, bufferPtrSize+1);

while (dataEncrypted < dataToEncrypt)
{
    bool final = (dataToEncrypt - dataEncrypted) <= lrcEncryptionBlockSize;

    if (final)
    {
        // Finalize everything to the output buffer.

        ccStatus = CCCryptorFinal(thisEncipher,
                                  szResult + dataEncrypted,
                                  bufferPtrSize - dataEncrypted,
                                  pOutSize
                                  );


        dataEncrypted += *pOutSize;

        for(int c=0;c<dataEncrypted;++c)
        {
            printf("\n%d => %d\n", c, szResult[c]);
        }

        success = true;
        break;
    }
    else
    {

    // Actually perform the encryption or decryption.
        ccStatus = CCCryptorUpdate( thisEncipher,
                                   szInput+cb,
                                   lrcEncryptionBlockSize,
                                   szResult+dataEncrypted,
                                   bufferPtrSize - dataEncrypted,
                                   pOutSize
                                   );   


        dataEncrypted += *pOutSize;

        cb += lrcEncryptionBlockSize;

    }
}

if (thisEncipher) {
    (void) CCCryptorRelease(thisEncipher);
    thisEncipher = NULL;
}

C#

        AesManaged aesAlg = new AesManaged();
        ICryptoTransform xfrm;

        aesAlg.IV = GenerateIV();
        aesAlg.Key = "1111111111111111";
        aesAlg.BlockSize = 128;

        xfrm = aesAlg.CreateEncryptor();

        while (dataEncrypted < dataToEncrypt)
        {
            bool final = (dataToEncrypt - dataEncrypted) <= lrcEncryptionBlockSize;
            int nbytes = !final ? lrcEncryptionBlockSize : (int)(dataToEncrypt - dataEncrypted); 

            if (final)
            {
                byte[] finalblock = xfrm.TransformFinalBlock(message, cb, nbytes);
                Buffer.BlockCopy(finalblock, 0, message, cb, lrcEncryptionBlockSize);
                success = true;
                break;
            }
            else
            {
                dataEncrypted += (uint)xfrm.TransformBlock(message, cb, nbytes, message, cb);
                cb += lrcEncryptionBlockSize;
            }
        }

        xfrm.Dispose();
        aesAlg.Clear();
Kenny Lim
  • 1,193
  • 1
  • 11
  • 31
  • 't is probably the padding as Erik suggests, otherwise you may have a look at line endings, null termination byte and such. One bit of difference makes at least one block of difference. – Maarten Bodewes Mar 13 '12 at 23:17
  • iOS uses PKCS7 to pad content, but so does AesManaged (by default). To discover the issue, encrypt some text with each implementation. Then decrypt with AesManaged & PaddingMode = None. Inspect the trailing bytes and you may find the culprit. Also this Q/A may be interesting to you: http://stackoverflow.com/questions/6461419/aescrypt-decryption-between-ios-and-php-fixed – Tails Mar 14 '12 at 03:13

1 Answers1

2

If only the last block differs, the difference is probably that they use different padding. The first example uses PKCS7, but I cant see what the second one uses.

Erik Ekman
  • 2,051
  • 12
  • 13