Working with AES encryption in IOS - ios

I am getting problem while encryption.
The server is sending json data which is aes256 encrypted and then base64 encoded.
while in the ios client side i am able to get the response and decode it using base64.
The AES256 decryption works on some libraries(3rd party or wrappers aroound CommonCryptor.h) and not working in another.
When decryption is working the parsing is not working.
The following are the wrappers libraries and the respective code.
RNCryptor
(https://github.com/rnapier/RNCryptor)
NSData *decodedData = [Util decode:data];
NSData *RNDecryptedData = [RNDecryptor decryptData:decodedData withPassword:randomString error:&error];
if (error == nil) {
NSLog(#"RNDecryptedData - %#",[Util hexStringFromData:RNDecryptedData]);
response = [NSJSONSerialization JSONObjectWithData:RNDecryptedData options:NSJSONReadingMutableContainers error:&error];
NSLog(#"response - %#",response);
NSLog(#"error1 - %#",error);
} else
NSLog(#"error2 - %#",error);
I am getting following error while decryption.
EncryptedParsing[4402:70b] error2 - Error Domain=net.robnapier.RNCryptManager Code=2 "Unknown header" UserInfo=0x8c6bd60 {NSLocalizedDescription=Unknown header}
CCrypto
(https://github.com/Gurpartap/AESCrypt-ObjC)
NSData *decodedData = [Util decode:data];
NSData *CCDecryptedData = [decodedData decryptedAES256DataUsingKey:randomString error:&error];
if (error == nil) {
response = [NSJSONSerialization JSONObjectWithData:CCDecryptedData options:NSJSONReadingMutableContainers error:&error];
NSLog(#"response - %#",response);
NSLog(#"error1 - %#",error);
} else
NSLog(#"error2 - %#",error);
Here I am getting the decrypted data, but while parsing it is giving following error
EncryptedParsing[4469:70b] error1 - Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x8a51520 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
NSData+AES256
(http://pastie.org/426530)
NSData *decodedData = [Util decode:data];
NSData *AES256DecryptedData = [decodedData AES256DecryptWithKey:randomString];
response = [NSJSONSerialization JSONObjectWithData:AES256DecryptedData options:NSJSONReadingMutableLeaves error:&error];
NSLog(#"error - %#",error);
I am getting the decryption data, while parsing i am getting following error
EncryptedParsing[4646:70b] error - Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x8a710c0 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
Along with these I have also used CocoaSecurity (https://github.com/kelp404/CocoaSecurity)
But it is not working.
I am using NSData+Base64 (https://github.com/l4u/NSData-Base64) for base64 decoding
By the way there is no problem from server side(we tested it).
I want to know the error i am doing. Or is there any other way to achieve it

There is no universal standard way to encode AES encrypted data. You need agreement on both sides about how to encode the various metadata required.
RNCryptor is failing to decrypt because it expects the data to be in the RNCryptor format.
CCCrypto and AES256DecryptWithKey are probably interpreting the key differently than you intend. Neither verifies that the key you pass is correct, so you likely are getting garbage back. If that's the case, I would expect that for some messages you get garbage back, and for other messages you get nothing back, or an error.
RNCryptor has implementations in several languages if you need a cross-platform solution. If you are required to conform to a server format (which is likely not secure encryption from the looks of your code), then you'll need to provide the server code in order to determine the correct client code.

try to replace NSJSONReadingMutableLeaves with kNilOptions.

Related

Fairplay SPC request returns nil

I'm attemping to use the [AVAssetResourceLoadingRequest streamingContentKeyRequestDataForApp:contentIdentifier:options:error:]; method to obtain an SPC key but I'm getting nil returned to me instead of the intended SPC value. I am mainly referencing the provided example Fairplay application. I'm using an encoded request URL host string as a content identifier and a .DER certificate retrieved from the SPC server as the app data. Has anyone else experienced this issue?
NSString *hostString = [URL host];
NSData *assetId = [NSData dataWithBytes:[hostString cStringUsingEncoding:NSUTF8StringEncoding] length:[hostString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
NSData *certificate = (obtained via Key Server).
NSError *error;
NSData *SPC = [loadingRequest streamingContentKeyRequestDataForApp:certificate contentIdentifier:assetId options:nil error:&error]
The output of SPC here is nil. The full error description is as follows:
Error Domain=AVFoundationErrorDomain
Code=-11800 "The operation could not be completed"
UserInfo=0x170461980
{NSUnderlyingError=0x1740548e0 "The operation couldn’t be completed. (OSStatus error -12640.)",
NSLocalizedFailureReason=An unknown error occurred (-12640),
NSLocalizedDescription=The operation could not be completed}
It turns out that the test stream was not correctly encrypted using SAMPLE-AES encryption.

userInfo Keys used in Core Data Validation Errors Error

Trying to find out Core Data Errors Error, and looking inside userInfo in NSError returned by MOC's save method.
iphone-core-data-unresolved-error-while-saving
I am not able to make commends or raise questions due to my lack of points.
Can any one point out for me where following keys are defined in Apple Doc, NSValidationErrorObject, NSValidationErrorKey...etc?
My understanding is: if CoreData's Error code == NSValidationMultipleErrorsError, then NSError's userInfo(dictionary) will contain all detailed-single-error information, and all those detailed-single-error will be accessible from an Array stored under "NSDetailedErrorsKey" from userInfo.
I just don't see them (NSValidationErrorObject, NSValidationErrorKe...) in Core Data Constants Reference...??? Are they opaque ?
Thanks.
- (BOOL)saveData {
NSError *error;
if (![_sharedManagedObjectContext save:&error]) {
// If Cocoa generated the error...
NSString *message = nil;
if ([[error domain] isEqualToString:#"NSCocoaErrorDomain"]) {
// ...check whether there's an NSDetailedErrors array
NSDictionary *userInfo = [error userInfo];
if ([userInfo valueForKey:#"NSDetailedErrors"] != nil) {
// ...and loop through the array, if so.
NSArray *errors = [userInfo valueForKey:#"NSDetailedErrors"];
for (NSError *anError in errors) {
NSDictionary *subUserInfo = [anError userInfo];
subUserInfo = [anError userInfo];
// Granted, this indents the NSValidation keys rather a lot
// ...but it's a small loss to keep the code more readable.
NSLog(#"Core Data Save Error\n\n \
NSValidationErrorKey\n%#\n\n \
NSValidationErrorPredicate\n%#\n\n \
NSValidationErrorObject\n%#\n\n \
NSLocalizedDescription\n%#",
[subUserInfo valueForKey:#"NSValidationErrorKey"],
[subUserInfo valueForKey:#"NSValidationErrorPredicate"],
[subUserInfo valueForKey:#"NSValidationErrorObject"],
[subUserInfo valueForKey:#"NSLocalizedDescription"]);
}
}
// If there was no NSDetailedErrors array, print values directly
// from the top-level userInfo object. (Hint: all of these keys
// will have null values when you've got multiple errors sitting
// behind the NSDetailedErrors key.
else {
NSLog(#"Core Data Save Error\n\n \
NSValidationErrorKey\n%#\n\n \
NSValidationErrorPredicate\n%#\n\n \
NSValidationErrorObject\n%#\n\n \
NSLocalizedDescription\n%#",
[userInfo valueForKey:#"NSValidationErrorKey"],
[userInfo valueForKey:#"NSValidationErrorPredicate"],
[userInfo valueForKey:#"NSValidationErrorObject"],
[userInfo valueForKey:#"NSLocalizedDescription"]);
}
}
// Handle mine--or 3rd party-generated--errors
else {
NSLog(#"Custom Error: %#", [error localizedDescription]);
}
return NO;
}
return YES;
}
[1]: https://stackoverflow.com/questions/1283960/iphone-core-data-unresolved-error-while-saving
Following is the quoted from #quellish message, thanks #quellish!
Core Data validation errors are defined in CoreDataErrors.h. I am considering asking Apple to move that stuff out of core data and into Foundation, since Key Value Coding really "owns" validation. Validation errors should always have a errorCode value between NSValidationErrorMinimum and NSValidationErrorMaximum as well.
I have an example validation error that may be helpful to you.
Single validation error (only one property failed): Error Domain=NSCocoaErrorDomain Code=1560 "The operation couldn’t be completed. (Cocoa error 1560.)" UserInfo=0x2808ac0 {NSDetailedErrors=(
"Error Domain=NSCocoaErrorDomain Code=1670 \"Name must be John\" UserInfo=0x2805f30 {NSLocalizedDescription=Name must be John}",
"Error Domain=NSCocoaErrorDomain Code=1570 \"The operation couldn\U2019t be completed. (Cocoa error 1570.)\" UserInfo=0x28089c0 {NSValidationErrorObject=<Employee: 0xc003180> (entity: Employee; id: 0xc0031d0 <x-coredata:///Employee/t6FEF17D8-0306-4959-9BFB-4B806E6ED1302> ; da…
see full text
a multiple looks similar, with additional NSErrors in the array that is the value of the userInfo dictionary for the key NSDetailedErrorsKey.
Note that the top level NSError is a single error with the cocoa error domain and error code 1560. That is NSValidationMultipleErrorsError. That error should always contain additional errors under the NSDetailedErrorsKey.
hope that helps!

get JSON file or info from AFNetworking

I have piece of good working code that downloads and parses JSON from server and returns result in +JSONRequestOperationWithRequest:success:failure: of AFJSONRequestOperation. success (and also failure)part of method takes block as an argument with id JSON argument in it. If I understand right - this object is for representation of JSON file or it's content. I need to have a possibility to send this JSON file (or it's text representation in every other text format) to email, using MFMailComposeViewController. So, two questions:
how can I get this JSON content from this file?
do I need register .json filetype to have possibility to send it using MFMailComposeViewController?
how can I get this JSON content from this file?
You can get the JSON data response (before it's converted to Foundation objects by NSJSONSerialization) from
operation.responseString (as NSString), or
operation.responseData (as NSData).
You'll want the latter if you're going to attach it to an e-mail.
do I need register .json filetype to have possibility to send it using
MFMailComposeViewController?
You need to call [MFMailComposeViewController -addAttachmentData:mimeType:fileName:]. You can get the mime-type from the operation.response.allHeaderFields NSDictionary. You can also use the official standard, application/json, or text/json, which is commonly used as well.
The response in the succes if not JSON but the object representation of the JSON. Most likely a NSArray or NSDictionary.
What you need to do is either use a normal HTTP request and send that string to the MFMailComposeViewController or change the JSON object back into a JSON string:
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:JSON options:0 error:&error];
NSString *jsonString = nil;
if (jsonData) {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
} else {
NSLog(#"Error creating JSON: %#", error);
}
Then you can pass the jsonString in your MFMailComposeViewController.

NSJSONSerialization works on IOS 6 but not on IOS 5.0

I'm working on restoring iOS 5.1 compatibility to an app I shipped which requires 6.0 currently.
This code works perfectly under 6.0 but when running under 5.1 parsing returns a null object and an error when parsing the exact same JSON result.
NSData *responseData = [request responseData];
NSError *jsonError;
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&jsonError];
if ((responseData == nil) || (responseDict == nil)) {
// I only get here when running on 5.1
}
I tried weak linking the Foundation framework. The jsonError is
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Duplicate key for object around character 8.) UserInfo=0x11d58530 {NSDebugDescription=Duplicate key for object around character 8.}
I have validated my JSON and there is only a single instance of the object type at character 8 and character 8 is simply a colon:
{"site":{

NSJSONSerialization works on iOS6 but not on iOS5.1

I'm working on restoring iOS5.1 compatibility to an app I shipped which requires 6.0 currently.
This code works perfectly under 6.0 but when running under 5.1 parsing returns a null object and an error when parsing the exact same JSON result.
I tried weak linking the Foundation framework
The jsonError is -
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Duplicate key for object around character 8.) UserInfo=0x11d58530 {NSDebugDescription=Duplicate key for object around character 8.}
I have validated my JSON set with and there is only a single instance of the object type at character 8 and character 8 is simply a colon:
{"site":{
Here's the code...
NSData *responseData = [request responseData];
NSError *jsonError;
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&jsonError];
if ((responseData == nil) || (responseDict == nil)) {
// I only get here when running on 5.1
}
try a different reading option for the JSONSerialization?
NSJSONReadingAllowFragments
That is what I use for my iOS 6 version of my project

Resources