Search code examples
phpiosencryptionmcrypt

Objective-C version of PHP mcrypt_encrypt


From searching all around, I can find a number of links referencing similar issues, but nothing is quite working, its driving me mad....

Can someone please give me a step by step guide on how to write the following PHP code in Objective C.

We are creating some web service calls, which require encrypted content, and we have only been given PHP encrypt sample. To be clear we do not want to un-encrypt, we want to mirror this encryption process in IOS.

Many thanks

function encrypt($plainText) {

      $initVector = "mysite.com";      
      $key = base64_decode("GfSDfXS14U8I3YglEFrMjMOOnESUMxN3wRTt1TeDosY=");

      $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
      $padding = $block - (strlen($plainText) % $block);
      $plainText .= str_repeat(chr($padding), $padding);
      $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plainText, MCRYPT_MODE_CBC, $initVector);
      $crypttext64 = base64_encode($crypttext);

      return $crypttext64;
}

Solution

  • was answered here on apple dev forums.

    https://devforums.apple.com/message/791166#791166

    PHP uses wacky crypto IMO, although code seems to be doing it's best to avoid the wackiness (for example, AFAICT the padding code implements PKCS#7 padding). It's likely that the problem you're seeing relates to how PHP translates the string "mysite.com" into a valid AES-128 IV (whose length must necessarily match the block size, that is, 16 bytes). It's quite possible that PHP pads with zeroes (that seems to be the PHP way) but you'll have to research that on the PHP side of things.

    Beyond that this looks like a fairly common application of Common Crypto. You need to:

    o pass in the kCCOptionPKCS7Padding flag

    o not pass in the kCCOptionECBMode flag (so you get CBC)

    o use kCCAlgorithmAES128, kCCKeySizeAES128, and kCCBlockSizeAES128

    o do your own Base64 [1]

    With regards the last point, I recommend you do this last. Modify the PHP code to print the $key, $plainText, and $crypttext as a hex dump and then work with that on the iOS side. Once that's working, then add the Base64. That splits the problem in half, meaning that Base64 issues won't get conflated with your encryption issues.

    Finally, keep in mind that OS X has a handy-dandy Base64 encoder and decoder on the command line. For example, to get a hex dump of the encryption key in your sample, you can do this:

    $ openssl enc -d -base64 | hexdump -C GfSDfXS14U8I3YglEFrMjMOOnESUMxN3wRTt1TeDosY= ^D 00000000 19 f4 83 7d 74 b5 e1 4f 08 dd 88 25 10 5a cc 8c |...}t..O...%.Z..| 00000010 c3 8e 9c 44 94 33 13 77 c1 14 ed d5 37 83 a2 c6 |...D.3.w....7...| 00000020

    Share and Enjoy

    Thanks to eskimo1