Objective-C version of PHP mcrypt_encrypt

2019-06-07 23:56发布

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;
}

2条回答
我只想做你的唯一
2楼-- · 2019-06-08 00:18

That came very close to being a correctly executed CBC mode encryption using AES in PHP :) It's really a shame about the static, too short IV and the fact that the character encoding has not been specified (in case plainText is a string of characters instead of bytes).

Otherwise this very very much looks like AES-256 using CBC mode and PKCS#7 padding, so you can take any example in Objective-C to execute precisely that. You also would need a base 64 decoder of course.

You should however generate a random IV and prefix it to the ciphertext (secure random, which is tricky in PHP). The IV should have the same size as the block size of the underlying cipher, in the case of AES that would be 16 bytes. Then the decryption function should remove those bytes from the ciphertext and use them as IV.

Looking into integrity protection (Message Authentication Code or MAC) would also be a very good idea.

查看更多
贼婆χ
3楼-- · 2019-06-08 00:25

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

查看更多
登录 后发表回答