2012-11-07 14 views
6

Il mio gioco cocos2d salva i dati utilizzando la crittografia CCCrypt(). Io uso l'indirizzo mac come chiave di crittografia. Il file di salvataggio crittografato in IOS5 non può decifrare con lo stesso indirizzo mac in IOS6. Ciò significa che un utente che ha aggiornato il proprio gioco perderà tutti i suoi dati!CCCrypt crittografato con ios5 non può essere decodificato con ios6

C'è un modo per decrittografare il vecchio file?

Ecco il codice:

@implementation NSData (AESAdditions) 
- (NSData*)AES256EncryptWithKey:(NSString*)key { 
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise 
    char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused) 
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) 

    // fetch key data 
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

    NSUInteger dataLength = [self length]; 

    //See the doc: For block ciphers, the output size will always be less than or 
    //equal to the input size plus the size of one block. 
    //That's why we need to add the size of one block here 
    size_t bufferSize   = dataLength + kCCBlockSizeAES128; 
    void* buffer    = malloc(bufferSize); 

    size_t numBytesEncrypted = 0; 
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, 
              keyPtr, kCCKeySizeAES256, 
              NULL /* initialization vector (optional) */, 
              [self bytes], dataLength, /* input */ 
              buffer, bufferSize, /* output */ 
              &numBytesEncrypted); 

    if (cryptStatus == kCCSuccess) 
    { 
     //the returned NSData takes ownership of the buffer and will free it on deallocation 
     return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 
    } 

    free(buffer); //free the buffer; 
    return nil; 
} 
- (NSData *)AES256DecryptWithKey:(NSString *)key { 
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise 
    char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) 
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) 

    // fetch key data 
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

    NSUInteger dataLength = [self length]; 

    //See the doc: For block ciphers, the output size will always be less than or 
    //equal to the input size plus the size of one block. 
    //That's why we need to add the size of one block here 
    size_t bufferSize = dataLength + kCCBlockSizeAES128; 
    void *buffer = malloc(bufferSize); 

    size_t numBytesDecrypted = 0; 
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, 
              keyPtr, kCCKeySizeAES256, 
              NULL /* initialization vector (optional) */, 
              [self bytes], dataLength, /* input */ 
              buffer, bufferSize, /* output */ 
              &numBytesDecrypted); 

    if (cryptStatus == kCCSuccess) { 
     //the returned NSData takes ownership of the buffer and will free it on deallocation 
     return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; 
    } 

    free(buffer); //free the buffer; 
    return nil; 
} 
@end 
+0

Mi sono imbattuto in un problema simile passando da iOS4 a iOS5 e si è verificato un errore che si stava verificando e l'ignorato in 4 non è stato ignorato nello stesso modo in 5. In un caso il buffer è stato riempito fino a l'errore mentre nell'altro il buffer è stato troncato all'inizio del blocco. Ti suggerirei di cercare qualcosa di simile. –

+1

Non è necessario crittografare i dati in base all'indirizzo MAC. Se l'utente acquista un nuovo dispositivo, quindi ripristina da iTunes, non sarà in grado di decodificare i dati di salvataggio sul nuovo dispositivo. –

risposta

-3

Ok, ho trovato la soluzione.

Punto chiave qui:

aggiungo due metodi per NSData per cifrare e decifrare con il codice di base lib IOS5.

@implementation NSData (AESAdditions) 
-(NSData*)AES256EncryptWithKey:(NSString*)key; 
-(NSData *)AES256DecryptWithKey:(NSString *)key 

Ora, in IOS6 lib, NSData potrebbe essere cambiato, così due metodi lavorato diverso, non può decifrare il file crittografare in IOS5.

Nel mio codice basato su IOS6, ho scritto metodi nella mia classe. come questo:

- (NSData*)AES256EncryptWithKey:(NSString*)key data:(NSData *)data; 
- (NSData *)AES256DecryptWithKey:(NSString *)key data:(NSData *)data; 

il codice funzionare bene stessi come in IOS5.

0

Avresti bisogno di fornire dettagli su come è stato implementato il vostro crittografia, in particolare quali opzioni si è utilizzato.

La causa più comune di decrittografi non riusciti su iOS 6 nella mia esperienza è il bug CTR che hanno modificato/corretto. In iOS 5, c'era l'opzione kCCModeOptionCTR_LE che era una bugia. In realtà è crittografato con kCCModeOptionCTR_BE. In iOS 6, hanno risolto il problema e, se provassi ad utilizzare kCCModeOptionCTR_LE, riceverai un errore "non implementato". Ma CCCrypt() generalmente non usa la modalità CTR, quindi non so se questo si applica.

+0

Rob grazie, ho incollato il codice, non usare 'kCCModeOptionCTR_LE' – gordon

Problemi correlati