2013-01-10 26 views
7

Đây là phương pháp của tôi để sử dụng RNCryptor để mã hóa/giải mã chuỗi JSON mà tôi đang gửi tới dịch vụ web. Tôi đang sử dụng một biến tĩnh IV có thể là thực hành xấu nhưng xin đừng tập trung vào đó. Đây là cách tôi đang làm nó:RNCryptor không hoạt động với chuỗi JSON

Lưu ý: Tôi sử dụng loại NSData + Base64 Matt Gallagher đã tìm thấy here (ở dưới cùng của trang)

-(NSString*)encryptString:(NSString*)plaintext withKey:(NSString*)key error:(NSError**)error{ 
    NSData *data = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; 
    NSData *encryptionKey = [NSData dataFromBase64String:key]; 
    NSData *IV = [NSData dataFromBase64String:ENCRYPTION_IV]; 

    RNCryptorEngine *engine = [[RNCryptorEngine alloc] initWithOperation:kCCEncrypt settings:kRNCryptorAES256Settings key:encryptionKey IV:IV error:error]; 
    [engine addData:data error:error]; 
    NSData *encryptedData = [engine finishWithError:error]; 

    NSString *based64Encrypted = [encryptedData base64EncodedString]; 
    NSLog(@"Encrytped: %@", based64Encrypted); 
    return based64Encrypted; 
} 
-(NSString*) decryptString:(NSString*)cipherText withKey:(NSString*)key error:(NSError**)error;{ 
    NSData *data = [NSData dataFromBase64String:cipherText]; 
    NSData *encryptionKey = [NSData dataFromBase64String:key]; 
    NSData *IV = [NSData dataFromBase64String:ENCRYPTION_IV]; 

    RNCryptorEngine *engine = [[RNCryptorEngine alloc] initWithOperation:kCCDecrypt settings:kRNCryptorAES256Settings key:encryptionKey IV:IV error:error]; 
    [engine addData:data error:error]; 
    NSData *decryptedData = [engine finishWithError:error]; 
    NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding]; 
    NSLog(@"Decrypted: %@", decryptedString); 
    return decryptedString; 
} 

Khi tôi sử dụng một chuỗi như hello world nó hoạt động tốt . Khi tôi sử dụng một chuỗi như {"username":"developer","password":"abcdefG*12"} Tôi tưởng tượng nó hase cái gì để làm với mã hóa nhưng tôi thực sự biết những gì để sử dụng.

khi tôi mã hóa chuỗi đó, tôi nhận được chuỗi base64 và khi tôi cố gắng giải mã rằng tôi nhận được chuỗi rỗng.

CẬP NHẬT

Dường như nó không vì : trong chuỗi json. Điều đáng tiếc hơn là nó chỉ thất bại với chuỗi có định dạng json, tôi nghĩ đó là nguyên nhân : tôi đã thử trước tiên nhưng khi điều tra thêm nếu tôi đã phá vỡ bất kỳ yêu cầu nào của , '' đang làm việc. Nó hoạt động với các RNEncryptor tuy nhiên vì vậy tôi không chắc chắn những gì tôi đang làm sai. Dù bằng cách nào, tôi nghĩ rằng chúng tôi có thể thiết kế lại dòng chảy hiện tại

UPDATE 2

Đây là nơi tôi kêu gọi các phương pháp:

NSDictionary *credentials = @{@"username":@"developer",@"password":@"abcdefG*12"}; 
NSString *jsonString = [ credentials JSONStringWithOptions:JKSerializeOptionNone error:&error]; 
NSLog(@"json string: %@", jsonString); //OUTPUTS: {"username":"developer","password":"abcdefG*12"} 
CCGEncryption *encryptionObject = [[CCGEncryption alloc] init]; //THIS IS THE OBJECT WHERE THE encrypt/decrypt methods are 

NSString *encrypted = [encryptionObject encryptString:jsonString withKey:ENCRYPTION_KEY error:&error]; 
if(error){ 
    NSLog(@"Error:%@", error); //NO ERROR 
} 
NSString *decrypted = [encryptionObject decryptString:encrypted withKey:ENCRYPTION_KEY error:&error]; 
if(error){ 
    NSLog(@"Error:%@", error); //NO ERROR 
} 
NSLog(@"decrypted: %@", decrypted); //OUTPUT: decrypted: 
+0

Khi bạn nói "Tôi mã hóa chuỗi đó, tôi nhận được chuỗi base64 và khi tôi cố gắng giải mã rằng tôi nhận được giá trị null". bạn có nghĩa là mã hóa và giải mã? từ mã được đăng của bạn, tôi thấy bản rõ của bạn sử dụng mã hóa UTF8 và bản mã của bạn sử dụng Base64 không phải của những người nên có vấn đề với dấu hai chấm. Nếu hàm giải mã của bạn trả về 'null', thì có lẽ giá trị' error' đang được trả về. Giá trị của nó là gì? – jbtule

+0

@jbtule Tôi đã thêm mã nơi tôi sử dụng các phương pháp đó.Tôi đang sử dụng JSONKit để serialize NSDictionary để NSString – mkral

+0

@jbtule và có, tôi có nghĩa là mã hóa/giải mã Tôi đã chỉnh sửa bài đăng – mkral

Trả lời

3

Bạn sẽ không thu thập dữ liệu trả về bởi addData:. Động cơ mã hóa/giải mã khi bạn đi để bạn không phải giữ toàn bộ bản rõ và bản mã trong bộ nhớ. Nó không tích lũy dữ liệu trừ khi nó phải (vì lý do đệm). Tôi nghi ngờ rằng các bài kiểm tra đang hoạt động có độ dài khác với độ dài khác nhau.

Bạn đúng rằng việc sử dụng IV cố định là hành vi không tốt. Nếu bạn sử dụng cùng một IV và khóa trong nhiều thư, thì có thể kẻ tấn công sẽ khôi phục các phần của thư của bạn bằng cách so sánh các bản mã. Nếu bạn đang sử dụng AES-CBC mà không có một IV ngẫu nhiên và HMAC, thì AES của bạn không an toàn theo nhiều cách. Đó là vấn đề mà RNCryptor đã được xây dựng để giải quyết và tại sao định dạng dữ liệu lại trông như thế nào.

@jbtule là chính xác mà tôi không đặc biệt có ý nghĩa để mọi người sử dụng trực tiếp động cơ và không có nhiều tài liệu, nhưng không có vấn đề gì khi sử dụng nó và tôi có thể ghi lại nó tốt hơn để hỗ trợ điều đó. Điều đó nói rằng, động cơ chính nó là điên rồ đơn giản; Tôi vừa tạo ra nó như một cách để chia sẻ mã giữa bộ mã hóa và bộ giải mã. Không có nhiều lý do để sử dụng RNCryptor nếu bạn sẽ bỏ qua hầu hết các bảo mật mà nó cung cấp. Đối với các mã trên, nó sẽ đơn giản hơn rất nhiều để chỉ cần gọi một shot CCCrypt().

+0

Cảm ơn Rob vì đã giải thích rõ ràng. Tôi sẽ nói chuyện với nhà phát triển phụ trợ của chúng tôi về việc triển khai với IV ngẫu nhiên. Một câu hỏi tôi có là Định dạng Dữ liệu mà bạn sử dụng một số loại tiêu chuẩn? Cuối cùng, chúng tôi sẽ chuyển sang android và muốn làm điều đó ngay bây giờ. – mkral

+0

Không có định dạng chuẩn đơn giản nào mà tôi biết có thể bao gồm IV, muối và HMAC, vì vậy tôi phải cuộn một định dạng mới. Định dạng aescrypt là gần, nhưng bạn không thể cung cấp các muối ngẫu nhiên (và chúng không sử dụng PBKDF chuẩn). Định dạng chuẩn duy nhất mà tôi thấy rằng thực sự có thể mã hóa AES chính xác là CMS, nhưng nó * phức tạp hơn nhiều và được thiết kế chủ yếu cho các thư được ký chứng chỉ chứ không phải mã hóa đối xứng. Tôi đang tích cực tìm kiếm một định dạng để hỗ trợ, nhưng nó phải được an toàn. "Tiêu chuẩn" nổi tiếng nhất là OpenSSL, nhưng định dạng AES của nó bị hỏng theo nhiều cách. –

+0

Ok tuyệt vời, cảm ơn bạn đã giải thích! – mkral