AES interoperability between .Net and iPhone
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.
Categories: code .Net, AES, AesCryptoServiceProvider, CommonCrypto, cryptography, encryption, iPhone, Objective C


Thanks for posting this code!
This is great, thanks for the example, it works perfectly.
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
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
thank you dude!
You got me out of my illiteracy…
@ mark:
had the same problem, there’s a bug in the base 64 file.
Excellent work dude.
Thanks a lot.
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
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
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.
Thank you so much for finding this! I was trying to figure this out over a year ago and eventually had to move on.
Just discovered this post while searching for iphone->.NET crypto interop. Did the base 64 bug get addressed?
Thanks!
you guys are chittah (jaguars) – kudos and many thanks!
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
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
Thanks for the code, it gives the clear idea for encrypting data on the iPhone and decrypting it using .Net.
YOU ARE THE MAN !!!!
saved me !
thanks everyone for fixing the Base64 Problem !!!!
Thanks. very nice code. it helps very much…
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
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
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?
Thank you all!! This helps very much!!!
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.
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.
@ 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.
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!
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…
@ Spare I found the error Spare It’s in the padding In the Obj C it uses PKCS7 and zero padding I just used PKCS7 and works just fine now. It took me a week to find it and it was right under my nose. I’ll change the encryption code to 256 bits to. Works great now. Thanks for the code David great job and thanks Spare for answering to my help .
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?
hey it does not work Spare and Radu. how did you set it to PKCS7. it seems to be PKCS7 already?
thanks
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 );
}
*/
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];
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
Thanks for your great work and share.
Mike nailed it… the DecryptString method now works for me. I’m decoding Base64 encoded strings from a .NET web service. Thanks!
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.
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!
Does anyone know how to convert unicode to base64 within the xcode code sample? any help would be appreciated!
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.
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!
Please disregard my question. If I’m not mistaken it’s using AES/CBC/PKCS7Padding.
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.
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!
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
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
guyz, anyone getting different strings on iphone and c# after encryption,please use key of length 16 char while encrypting.
it works….thanx
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
Thanks Mike, after making those changes you mentioned, my code works. You rock!