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.
David
Thanks for posting this code!
Ryan
This is great, thanks for the example, it works perfectly.
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
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
Saag
thank you dude!
You got me out of my illiteracy…
joofus
@ mark:
had the same problem, there’s a bug in the base 64 file.
Shiv
Excellent work dude.
Thanks a lot.
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
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
Russ Freeman
Many thanks to you and bb – this has saved me loads of time
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.
Denny Ferrassoli
Thank you so much for finding this! I was trying to figure this out over a year ago and eventually had to move on.
Rpmobile
Just discovered this post while searching for iphone->.NET crypto interop. Did the base 64 bug get addressed?
Thanks!
jeet
you guys are chittah (jaguars) – kudos and many thanks!
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
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
Guna
Thanks for the code, it gives the clear idea for encrypting data on the iPhone and decrypting it using .Net.
Karloz
YOU ARE THE MAN !!!!
saved me !
thanks everyone for fixing the Base64 Problem !!!!
Mitesh Khatri
Thanks. very nice code. it helps very much…
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
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
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?
FU
Thank you all!! This helps very much!!!
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.
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.
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.
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!
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…
Radu
@ 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 .
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?
joshua
hey it does not work Spare and Radu. how did you set it to PKCS7. it seems to be PKCS7 already?
thanks
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 );
}
*/
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];
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
osman cevik
Thanks for your great work and share.
Ken
Mike nailed it… the DecryptString method now works for me. I’m decoding Base64 encoded strings from a .NET web service. Thanks!
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.
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!
Dan D.
Does anyone know how to convert unicode to base64 within the xcode code sample? any help would be appreciated!
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.
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!
Arci
Please disregard my question. If I’m not mistaken it’s using AES/CBC/PKCS7Padding.
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.
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!
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
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
virat
guyz, anyone getting different strings on iphone and c# after encryption,please use key of length 16 char while encrypting.
it works….thanx
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
Shannon
Thanks Mike, after making those changes you mentioned, my code works. You rock!
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
Gianni
Thanks u all guys, it was 3 days I was searching for a solution!
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
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 ?
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!
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?
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;