2015年5月14日 星期四

Objective-C: AES 加密解密

為容戶重製的應用程式中,不止圖檔會被加密,連客戶端及服務器端的溝通都會被加密。那麼,客戶端收到數據後便需要進行解密,同時處理完的資訊又要加密後才發到服務器。因此,需要為客戶端編寫加密解密的程序。參考了Zhiwei Li 的 iPhone上AES加密的实现,稍作修改後便能使用。下面的代碼就是運用了加密解密的部份:
NSDictionary *jsonDictionary = @{
    @"deviceID": deviceID,
    @"appVersion": appVersion,
    @"jailBroken": jailBroken,
    @"timeStamp": timeStamp
};

//--------------------------------------------------------------------------------------------------
//  Encode to JSON data
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

//  Convert JSON to AES-256
NSString *aesString = [jsonString aes256EncryptWithKey:APPMANAGER_KEY_AES256];

//  Calculate checksum
NSString *checkSumString = @"checkSum";

//--------------------------------------------------------------------------------------------------
//  Send it out to server
NSString *urlString = [APPMANAGER_API_HOST stringByAppendingString:APPMANAGER_API_REGISTER];
NSDictionary *dictionary = @{
    @"data": aesString,
    @"checkSum": checkSumString
};

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:urlString parameters:dictionary success:^(AFHTTPRequestOperation *operation, id responseObject)  {
    
    //--------------------------------------------------------------------------------------------------
    //  Success, but never mind the result, just for record
    NSDictionary *dictionary = (NSDictionary *)responseObject;
    NSString *dataString = [dictionary objectForKey:@"data"];

    NSString *plainText = [dataString aes256DecryptWithKey:APPMANAGER_KEY_AES256];
    BZLog(@"Connection done! %@", plainText);

}  failure:^(AFHTTPRequestOperation *operation, NSError *error)  {
    
    //--------------------------------------------------------------------------------------------------
    //  Failed, but never mind the result, just for record
    BZLog(@"### %@", [error localizedDescription]);
}];

有一點要留意,就是加密解密要使用相同的算法及長度。我經過反覆測試後,選擇了 AES 256bits 及 ECB 模式。原因是使用 CBC 時發現解碼不能 100% 正確。

沒有留言: