2

How are you?

I'm trying to use RNCryptor to encrypt my transactions between the iOS devices and the webserver. For that I'm using RNCryptor on iOS and PHP, and AFNetworking to communicate from iOS to WebServer.

How do I decrypt data received from AFNetworking before it's been parsed to JSON response object?


To synthesize, I have:

  • Yii Framework, server side, PHP
  • AFNetworling, client side, Objective-C
  • RNCryptor, both sides

From iOS to PHP: I can decrypt data before using it.

From PHP to iOS: AFNetworking do not decrypt data before using it.


My PHP code is something like that:

RNCryptorHelper::init();
$encryptor = new \RNCryptor\Encryptor;

$data['Model1'] = Model1::model()->findAll();
$data['Model2'] = Model2::model()->findAll();

// EDITED TO REMOVE THIS HEADER
// header('Content-type: application/json');
echo $encryptor->encrypt(CJSON::encode($data), Yii::app()->params['cryptPassword']);
Yii::app()->end();

That outputs something like that:

AwFQ9+OfsHyXcSPynCrtveF7MQupQ+urd/VYeNMmt6OMxd6MhsDz4nxapvS1kVEHHbBZ4xLHqN7hTUDZos1LTWhB/CyeYoWpZSDhyFeHu9wNlHcRie6KTaHv/h14krvfb2/GHMt3GhIFqnyo7UKy/d06


My Objective-C code is something like that:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

[manager GET:[NSString stringWithFormat:@"%@/Sync", URL_ROOT]
  parameters:nil
     success:^(AFHTTPRequestOperation *operation, id responseObject) {

         NSLog(@"%@", [RNDecryptor decryptData:responseObject withPassword:CRYPT_PASSWORD error:nil]);

     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error) {
         NSLog(@"Error: %@", error);
     }];

That outputs the following 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=0x15681970 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}


Thanks for your help!!


EDIT 1

I changed the code a little bit and now I can get the result:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

[manager GET:[NSString stringWithFormat:@"%@/Sync", URL_ROOT]
  parameters:nil
     success:^(AFHTTPRequestOperation *operation, id responseObject) {

         NSData *decryptedData = [RNDecryptor decryptData:[[NSData alloc] initWithBase64EncodedData:responseObject options:NSDataBase64DecodingIgnoreUnknownCharacters]
                                             withPassword:CRYPT_PASSWORD
                                                    error:nil];

         id json = [NSJSONSerialization JSONObjectWithData:decryptedData
                                                   options:kNilOptions
                                                     error:nil];

     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error) {
         NSLog(@"Error: %@", error);
     }];

Anyone has a hint on how to create a Response Serializer that automates that decrypt?

4

2 回答 2

3

好的,找到了解决方案并以一种漂亮的方式解决了。我创建了一个处理解密的 AF 响应序列化程序。

RNCryptResponseSerializer.h

//
//  RNCryptResponseSerializer.h
//  Professor Virtual
//
//  Created by Caio Henrique Galli dos Santos on 18/06/14.
//  Copyright (c) 2014 sys10. All rights reserved.
//

#import "AFURLResponseSerialization.h"

@interface RNCryptResponseSerializer : AFJSONResponseSerializer

@end

RNCryptResponseSerializer.m

//
//  RNCryptResponseSerializer.m
//  Professor Virtual
//
//  Created by Caio Henrique Galli dos Santos on 18/06/14.
//  Copyright (c) 2014 sys10. All rights reserved.
//

#import "RNCryptResponseSerializer.h"
#import "RNDecryptor.h"

@implementation RNCryptResponseSerializer

#pragma mark - AFURLResponseSerialization

- (id)responseObjectForResponse:(NSURLResponse *)response
                           data:(NSData *)data
                          error:(NSError *__autoreleasing *)error
{

    NSData *dataFromBase64 = [[NSData alloc] initWithBase64EncodedData:data options:NSDataBase64DecodingIgnoreUnknownCharacters];
    NSData *dataDecrypted = [RNDecryptor decryptData:dataFromBase64
                                        withPassword:CRYPT_PASSWORD
                                               error:nil];

    return [super responseObjectForResponse:response data:dataDecrypted error:error];

}

@end

在我的 AFHTTPRequestOperationManager 上:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [RNCryptResponseSerializer serializer];

[manager GET:[NSString stringWithFormat:@"%@/Sync", URL_ROOT]
  parameters:nil
     success:^(AFHTTPRequestOperation *operation, id responseObject) {

         // Decrypted responseObject
         responseObject;

     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error) {
         NSLog(@"Error: %@", error);
     }];
于 2014-06-19T13:46:49.310 回答
1

您在响应标头中说返回的数据将是 JSON('Content-type: application/json'),但事实并非如此,它只是一堆曾经是 JSON 的加密字节,并且可以在解密后再次出现。

更改标头(最佳)或使用看不到标头的 http 请求并自动尝试反序列化 JSON。查看 AAFNetworking 并查看是否有这样的选项或其他仅返回 rad 数据的方法。

您需要获取原始数据,对其进行解密,然后对其进行反序列化。

于 2014-06-18T23:31:46.613 回答