AES interoperability between .Net and iPhone

Posted by & filed under code.

One of my projects requires encrypting data on the iPhone and decrypting it using .Net. This is easy to do with the Common Crypto library in the iPhone SDK and the AesCryptoServiceProvider class in .Net, but the encryption parameters have to be the same for it to work.

I couldn’t figure it out, but the geniuses at StackOverflow did, so I am posting my results here. The zip file includes a basic iPhone app and a .Net console project with helpful classes to do the encryption/decryption and base64 conversion. I didn’t write most of the code – thanks to Blue Beetle for the .Net code and Greg Haygood for the Objective C.

Download zip.

62 Responses to “AES interoperability between .Net and iPhone”

  1. checcco

    Hi, this is just what i was looking for… but i need decryption in PHP…:(

    I’m thinking to buy this: http://www.phpaes.com on their site there’s a demo utility to encrypt or decrypt strings…but i cant get the same result as the iphone program you provided… would you please try, too? maybe im messing with mode and iv..thanks so much

    Reply
  2. Mark

    hi, a quick question
    i get encrypted data to export as NSString say “u+8tQsPIHhr1Ll5TKBdbdSZmLEX/cD/xYY34kLPIPFc=”

    which is good, if I decrypt encrypted data it works but when I take this export string (above) and try to created NSDATA object
    NSData* encData = [NSData dataWithBase64EncodedString:"u+8tQsPIHhr1Ll5TKBdbdSZmLEX/cD/xYY34kLPIPFc="];

    then i cannot get encoded string decoded.

    Here is full sample:

    NSString * _secret = @”My Encryption Key”;
    NSString * _key = @”1234123412341234″;

    StringEncryption *crypto = [[[StringEncryption alloc] init] autorelease];
    NSData *_secretData = [_secret dataUsingEncoding:NSUTF8StringEncoding];
    CCOptions padding = kCCOptionPKCS7Padding;
    NSData *encryptedData = [crypto encrypt:_secretData key:[_key dataUsingEncoding:NSUTF8StringEncoding] padding:&padding];

    NSString* encDataToExport = [encryptedData base64EncodingWithLineLength:0];

    // do reverse -> from encrypted data to unencrypted

    NSData* encData = [NSData dataWithBase64EncodedString:encDataToExport]; // gives me 427 bytes somehow!!!!!!!!!

    NSData* decryptedData = [crypto decrypt:encData key:[_key dataUsingEncoding:NSUTF8StringEncoding] padding:&padding]; // returns nil

    NSString* str = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
    NSLog(@”str: %@”,str);

    I think i am not converting encoded string correctly to base64 data.
    What am I missing?

    Thank you
    Mark

    Reply
  3. locoVJ

    Thanks for the Code.
    When I use this code on iPhone for hello/hello the encoded string is not QA+Ul+r6Zmr7yHipMcHSbQ==
    Can you please verify there is ssome problem with the Base64
    Thanks,
    locoVJ

    Reply
  4. bbb

    Because this was so helpful…

    There seems to be a bug in the base64 file. The line with inbuf[3] outbuf[4] should be inbuf[4] outbuf[3].

    And you need to use the base64 stuff if you are working off the .NET example.. So something like

    NSData * encdata = [NSData dataWithBase64DecodedString:the_encrypted64strfromweb];

    NSData* decData = [crypto decrypt:encdata ….

    ————–

    Oh, and just use a 16 character key right off the bat….

    Thanks

    Reply
  5. Ben

    Thanks for the code. It is very useful for me.
    And I would also like to thanks bbb. Otherwise, I cannot still find a way to decrypt the base32 string.

    Reply
  6. Rpmobile

    Just discovered this post while searching for iphone->.NET crypto interop. Did the base 64 bug get addressed?

    Thanks!

    Reply
  7. jeet

    by the way guys, I am looking for interoperability between .Net and iPhone for compression mechanism, currently I am trying gZip that available in both platforms, but luck is not my way,
    strings which i compressed from both mechanism gives me different decompressed strings

    many thanks
    Jeet

    Reply
  8. jeet

    I am not taking my words back… you guys are great, but I struck at ground :( I was testing both versions in and out.
    I am encrypting a string in objective-c and also encrypting the same string in C# using AES and am seeing some strange issues. The first part of the result matches up to a certain point but then it is different. Why?

    I am using a source string of “this is going to be test and fingers are crossed” Using a key of “1234567891123456″

    The result from Objective C is 5U6TAlyma3GbR5UYqyk7d7mdTY1Jy9obUTwlOaL0/wn72s7IVZQPi1zydeonLSqP

    The result from C# is
    5U6TAlyma3GbR5UYqyk7d7mdTY1Jy9obUTwlOaL0/wn72s7IVZQPi1zydeonLSqPwifBaSjG51fj6y4S
    j7cS7w==

    you notice that initial portion of strings are same but then it starting differs.

    I’ve not added/modified anything except for those string and key.
    Please assist… I am in do/die situation :(

    thanks
    Jeet

    Reply
  9. Guna

    Thanks for the code, it gives the clear idea for encrypting data on the iPhone and decrypting it using .Net.

    Reply
  10. Karloz

    YOU ARE THE MAN !!!!

    saved me !

    thanks everyone for fixing the Base64 Problem !!!!

    Reply
  11. Ken

    Just for info, you have a error in the md5data function :
    old : NSString* temp = [NSString stringWithFormat:
    @”02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X”,

    New : NSString* temp = [NSString stringWithFormat:
    @”%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X”,

    (miss % on the beginning of the string)

    But the code helpes me some, thank

    Reply
  12. Terry in SD

    Hey Folks,

    Thanks David for posting this, and everyone else for finding and fixing bugs. In case anyone else just downloaded the ZIP file, here are the line numbers to make the changes mentioned in the comments:

    Reversed buffer sizes for inbuf and outbuf is in NSData+Base64.m at line 36

    The missing % is in StringEncryption.m at line 266

    Reply
  13. Myke Koscielski

    Thanks for the corrections on this. Works good. I also need to have a way to use the same key and encryption technique from javascript. I’ve looked at a few AES javascript samples, but they don’t seem to come up with the same encrypted/decrypted values when I use the key I’ve used with this solution. Anyone have any good javascript that match this one?

    Reply
  14. Radu

    This is great work but i have a question, It only works with keys that are %8 = 0 keys, for example if i have an encryption key _Key=123456789 i will get diffrent results in .net and iphone , if i use a key _Key%8= 0 works perfectly why is that? And how do i fix it if anybody can help i wil greatly appreciated.

    Reply
  15. Radu

    Does the code have some bugs in it or am i doing something wrong?
    I implemented the encryption codes. sent a message to the web service, when I recived the encrypted message from the web service the iphone is unable to decypt the message. it creates extra characters in the string. This does not happend for all messages.
    Please help i really don’t want to create a compatible algorithm from scrach. i am new to encrypting algorithms. i am testing it on the Iphone Simulator and the web service is on a .net dedicated server.

    Reply
  16. Radu

    @ jeet
    I got the same problem. Did you fix it ? i have no idea what’s wrong and I really need to get an working encryption fast.

    Reply
  17. Spare

    Thank you for this article! I was looking for something like this! I’m testing it now on the iPad vs a .NET webservice. I’ve changed the key to 256 bits. Seems to work like a charm!

    Reply
  18. Spare

    I checked the problems from Radu and jeet and indeed there seems to be a bug in the code when the text to be encrypted is 16/32/48/etc characters? Seems the ObjC code forgets a part there…

    Reply
  19. Spare

    It was the padding, indeed. I figured it out, too, haha. Now the code is completely interoperable between .NET and Objective C :)

    One thing I’m asking, It’s not really a problem but it annoys me a bit, that every time a same string is entered the same base64 code is generated. I’m looking for a way for it to be completely different each time, even if you enter the same string as input. Is there a way to match this on both sides?

    Reply
  20. joshua

    hey it does not work Spare and Radu. how did you set it to PKCS7. it seems to be PKCS7 already?
    thanks

    Reply
  21. Spare

    I commented the padding section out:

    // We don’t want to toss padding on if we don’t need to
    /*
    if(encryptOrDecrypt == kCCEncrypt) {

    ….

    NSLog(@”Invalid CCOperation parameter [%d] for cipher context.”, *pkcs7 );
    }
    */

    Reply
  22. mike

    Hi, thank for your code, its very usefull for me, i found 2 small – but important – bugs.

    1; NSData+Base64.m file, initWithBase64EncodedString method here should be: unsigned char inbuf[4], outbuf[3];

    2; StringEncryption.m file, DecryptString method here should be:
    NSData *data = [crypto decrypt:[NSData dataWithBase64EncodedString:base64StringToDecrypt] key:[_key dataUsingEncoding:NSUTF8StringEncoding] padding: &padding];

    Reply
  23. pk

    After making the changes the iPhone encrypted password still does not match the .net result. Can someone please post the updated objective code or point to the changes please.

    Thanks

    Reply
  24. Ken

    Mike nailed it… the DecryptString method now works for me. I’m decoding Base64 encoded strings from a .NET web service. Thanks!

    Reply
  25. Ken

    I thought I had it all working perfectly but then one one particular encoded string differed between Obj-C and .NET. (Halfway through the Base64 string as people have reported.) I had not added Spare’s change to comment out the padding. That fixed it.

    Reply
  26. Dan D.

    The .net version seems not to be unicode-compatible. for example it can not convert the char ‘ä’ or ‘µ’ properly. Does anyone has a suggestion how to fix this?
    Thanks!

    Reply
  27. Dan D.

    Does anyone know how to convert unicode to base64 within the xcode code sample? any help would be appreciated!

    Reply
  28. Vittal

    Hi All, implemented this algorithm.
    I am facing following problem.
    1. iphone encrypting always with less number of characters length.
    2. .Net encrypting algorithm giving more number of characters in encrypted string than iphone encrypted string. Because of which, .Net service is not able to decrypt iphone encrypted string.
    Could you please point me where I am doing wrong here. Thanks in advance.

    Reply
  29. Arci

    Hi. By any chance, do you also have a similar code for Java? May I also know what algorithm, mode and padding (e.g. AES/CBC/PKCS7Padding) your code uses? Thank you!

    Reply
  30. Arci

    Please disregard my question. If I’m not mistaken it’s using AES/CBC/PKCS7Padding.

    Reply
  31. andsakk

    Hello, Great post appreciates such valuable information. I am about to use these algorithms within the asp.net web services and the app I am currently developing.
    Does anyone know if you require to declare for CCATS for using these libraries or can we just waive the CCATS requirement since we are using IOS inbuilt crypto in this AES?

    I am from Australia, and I hear lots of complications on using cryptography in your apps and having to declare information to ENC Encryption etc.

    Any information would be highly appreciated! Thanks folks.

    Reply
  32. Kyle

    Hello – after reading all of the comments and attempting to encrypt/decrypt a string between a .NET app and iOS, I’m getting different results. And neither side can decrypt the encrypted value generated by the other.

    I’ve tried updating my project based on all of the comments, but still no luck… If anyone would have the complete list of updates and/or a working copy of this project, I would greatly appreciate it.

    Thank you!

    Reply
  33. Sachin

    Hi,
    This is really very great post and very helpful.
    I am in need of android version too. If possible please post the code I will be very thankful for you.
    Waiting for you response :)

    Reply
  34. Sachin

    Hi,
    This is really very great post and very helpful.
    I am in need of android version too. If possible please post the code I will be very thankful for you.
    Waiting for you response :)

    Reply
  35. virat

    guyz, anyone getting different strings on iphone and c# after encryption,please use key of length 16 char while encrypting.
    it works….thanx

    Reply
  36. Tommy

    Hi Guys,

    just to clarify things. the .net and iOS source do provide the same crypto-values in most cases. in some like “kochhofstrasse 7″ they don’t. as “Spare” reported in a comment above, to fix this
    - just comment the section below this comment out: “// We don’t want to toss padding on if we don’t need to”
    -use a 16 char key, while encrypting (123456789012345)
    -use UTF8 Encoding where its using ASCII (on server and client, to avoid umlaut-problems)

    then you should be good to go! good luck!
    take care
    Tommy

    Reply
  37. Shannon

    Thanks Mike, after making those changes you mentioned, my code works. You rock!

    Reply
  38. Felipe

    I’m having problem with the code… does not encrypt the same on iOS as .Net.
    Can someone help me, i have done the changes that Mikes says and steal doesn’t works.
    Thx

    Reply
  39. Mesut

    Mike’s solution didn’t solve my problem, but i tried;

    NSData *data = [crypto decrypt:[[NSData alloc] initWithBase64EncodedString:base64StringToDecrypt] key:[_key dataUsingEncoding:NSUTF8StringEncoding] padding: &padding];

    There is a class which is overriding NSData. Also people can use (initWithBase64EncodedString) this way. Maybe there are people like me :)

    Reply
  40. Mecha

    Hi,

    I just faced a Decrypt problem.

    When i define a encrypted string for decrypting. Im getting “Problem with encipherment ccStatus == -4301″ (which means “kCCBufferTooSmall”) error in StringEncryption file.

    How can i solve it ? Any help ?

    Reply
  41. Adrian

    This is fantastic, thanks VERY much for sharing. Finding this brought an end to 3 very frustrating days!!

    My comments to help fellow travellers: Make sure you implement the changes for the iOS version highlighted by Spare and Terry in SD above.

    Also, took me a bit to figure out: to decrypt a string in the iOS version, get the NS data by doing:
    NSData *_transferredData = [NSData dataWithBase64EncodedString:strTransferred]; //strTransferred is the string received from .NET

    then:
    NSData *decryptedTransferredData = [crypto decrypt:_transferredData key:[_key dataUsingEncoding:NSUTF8StringEncoding] padding:&padding];
    NSString *decryptedString = [[NSString alloc] initWithData:decryptedTransferredData encoding:NSUTF8StringEncoding];

    Cheers!

    Reply
  42. Rachit

    Hi,

    Thanks for posting this. I have a problem coming in the code. I am getting encrypted string from the server and want to decrypt it at iPhone end. Can you please tell me how to use the above code for that?

    Reply
  43. Aj

    I am Implementing the AES128 bit encryption/Decryption in iOS application for sending/receiving data from .net server, I almost done but during unit testing I got some issue in encryption string, some encrypted string are not similar as on .net server, Can say 98 percent are correct but in 2 percent issue comes, when I match the both side encrypted string then found at iOS end generated string is little short and .net end it is long string. One more thing i found the iOS string is the substring of .net string. When i tried to decrypt the iOS generated encrypted string, it is not decrypted showing null but when I try to decrypt the .net server generated encrypted string (it was larger than the iOS) I am able to se the decrypted string.

    Using the same KEY(16 character long at server and iOS end).

    could you please suggest the solution or where I am wrong .

    Thanks a lot to all.

    Original string: “custId=10&mode=1″ KEY= “PasswordPassword”

    at iOS encrypted string: r51TbJpBLYDkcPC+Ei6Rmg==

    at .net encrpted string: r51TbJpBLYDkcPC+Ei6RmtY2fuzv3RsHzsXt/RpFxAs=

    padding for encryption = kCCOptionPKCS7Padding;

    Reply

Leave a Reply