2013-01-10 11 views
7

Ecco i metodi per utilizzare RNCryptor per crittografare/decodificare una stringa JSON che sto inviando al servizio web. Sto usando una variabile IV statica che potrebbe essere una cattiva pratica, ma per favore non concentrarsi su questo. Ecco come lo sto facendo:RNCryptor non funziona con la stringa JSON

Nota: sto usando di Matt Gallagher categoria NSData + Base64 trovato here (in fondo alla pagina)

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

Quando uso una stringa come hello world funziona benissimo . Quando uso una stringa come {"username":"developer","password":"abcdefG*12"} immagino che abbia qualcosa a che fare con la codifica, ma so davvero cosa usare.

quando crittografo quella stringa ottengo una stringa base64 e quando provo a decodificare ottengo una stringa vuota.

UPDATE

Sembra come se fosse mancata a causa della : nella stringa JSON. Cosa c'è di strano è fallisce solo con la stringa è in formato JSON, ho pensato che fosse il : causa ho provato prima, ma dopo ulteriori indagini, se ho rotto uno dei requisiti JSON , s 's {' } 's si è fermato lavoro. Funziona con lo RNEncryptor tuttavia non sono sicuro di cosa sto facendo male. Ad ogni modo, penso che possiamo ridisegnare il flusso di corrente

UPDATE 2

qui è dove sto chiamando questi metodi:

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

Quando si dice "I encode that string ottengo una stringa base64 e quando provo a decodificare ottengo un valore nullo." stai volendo criptare e decifrare? dal tuo codice postato, vedo che il tuo testo normale utilizza la codifica UTF8 e il tuo testo cifrato utilizza Base64 nessuno di questi dovrebbe avere problemi con i due punti. Se la funzione di decrittografia restituisce 'null', allora probabilmente viene restituito un valore' error'. Qual è il suo valore? – jbtule

+0

@jbtule Ho aggiunto il codice dove uso questi metodi.Sto usando JSONKit per serializzare NSDictionary su NSString – mkral

+0

@jbtule e sì, volevo cifrare/decodificare Ho modificato il post – mkral

risposta

3

Lei non è la raccolta dei dati restituiti da addData:. Il motore crittografa/decodifica mentre si va in modo da non dover tenere in memoria l'intero testo in chiaro e il testo cifrato. Non accumula i dati a meno che non debba (per motivi di riempimento). Sospetto che i test che stanno lavorando siano di lunghezza diversa da quelli che non lo sono.

Si è corretto che l'utilizzo di un IV fisso è una cattiva pratica. Se si utilizzano lo stesso IV e la stessa chiave in più messaggi, è possibile che gli autori di attacchi recuperino parti dei propri messaggi confrontando i testi cifrati. Se si utilizza AES-CBC senza un IV casuale e un HMAC, allora l'AES non è sicuro in diversi modi. Questo è il problema per cui RNCryptor è stato creato per rispondere e perché il formato dei dati è simile a quello che fa.

@jbtule è corretto che non intendevo particolarmente che le persone usassero direttamente il motore e non lo avessero documentato pesantemente, ma non ci sono problemi ad usarlo e posso documentarlo meglio per supportarlo. Detto questo, il motore stesso è incredibilmente semplice; L'ho appena creato come un modo per condividere il codice tra il codificatore e il decryptor. Non ci sono molti motivi per usare RNCryptor se si vuole bypassare la maggior parte della sicurezza che fornisce. Per il codice di cui sopra, sarebbe molto più semplice chiamare semplicemente lo CCCrypt() one-shot.

+0

Grazie Rob per averlo spiegato molto chiaramente. Parlerò con il nostro sviluppatore di backend sull'implementazione con IV casuale. Una domanda che ho avuto è il formato dati che usi una sorta di standard? Alla fine passeremo ad Android e vogliamo farlo adesso. – mkral

+0

Non c'è un formato standard semplice che io sappia che possa includere IV, sali e un HMAC, quindi ho dovuto lanciarne uno nuovo. Il formato aescrypt è chiuso, ma non puoi fornire sali casuali (e non usano un PBKDF standard). L'unico formato standard che ho trovato che può effettivamente codificare AES correttamente è CMS, ma è * molto * più complicato e progettato principalmente per i messaggi con firma dei certificati, non per la crittografia simmetrica. Sto cercando attivamente un formato da supportare, ma deve essere sicuro. Lo "standard" più conosciuto è OpenSSL, ma il suo formato AES è rotto in diversi modi. –

+0

Ok bene, grazie per la spiegazione! – mkral