2014-06-18 67 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); 
    }];