2014-06-18 43 views
2

你好吗?AFNetworking + RNCryptor - 在JSON解析之前解密数据

我想使用RNCryptor加密我的iOS设备和网络服务器之间的交易。为此,我在iOS和PHP上使用RNCryptor,并使用AFNetworking从iOS与WebServer进行通信。

在解析为JSON响应对象之前,如何解密从AFNetworking接收到的数据?


要合成的,我有:

  • Yii框架,服务器端,PHP
  • AFNetworling,客户端,Objective-C的
  • RNCryptor,双方

从iOS到PHP:我可以在使用之前解密数据。

从PHP到iOS:AFNetworking在使用之前不会解密数据。


我的PHP代码是类似的东西:

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(); 

输出这样的事情:

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


我的Objective-C代码是什么像这样:

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); 
    }]; 

输出以下错误:

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.}


感谢您的帮助!


编辑1

我改变了代码一点点,现在我可以得到的结果:

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); 
    }]; 

任何人有关于如何创建一个响应串行器,它可以自动的提示解密?

回答

1

你说在响应头文件中返回的数据将是JSON('Content-type:application/json'),但它不是,它只是一堆加密字节,一次是JSON,可以再次后解密。

要么更改标头(最好),要么使用没有看到标头的http请求,并自动尝试去序列化JSON。看看AAFNetworking,看看是否有这样的选项或其他方法只是返回rad数据。

您需要获取原始数据,解密并将其反序列化。

+0

就是这样。我改变它来接收原始数据并解密它。现在我正在研究如何创建Response Serializer来处理它。 –

+0

完成!非常感谢你。 –

3

好的,找到了解决方案,并以美丽的方式解决。 我已经创建了一个处理解密的AF Response Serializer。

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); 
    }];