2012-11-07 19 views
6

我的cocos2d遊戲使用CCCrypt()加密保存數據。我使用mac地址作爲加密密鑰。在IOS5中加密的保存文件不能使用IOS6中的相同MAC地址進行解密。這意味着更新遊戲的用戶將失去所有數據!用ios5加密的CCCrypt不能用ios6加密

有什麼辦法解密舊文件嗎?

這裏是代碼:

@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

我遇到了一個類似的問題,從iOS4到iOS5,結果發生了一個錯誤,並且在4中被忽略,並沒有像5中那樣被忽略。在一種情況下,緩衝區被填充到另一個緩衝區在塊開始時被截斷。我建議你尋找類似的東西。 –

+1

您不應根據MAC地址加密數據。如果用戶購買新設備,然後從iTunes恢復,則他們將無法解密新設備上的保存數據。 –

回答

-3

好的,我找到了解決方案。

關鍵點的位置:

我添加了兩種方法來NSData的加密和基於代碼的IOS5 LIB解密。

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

現在,在iOS6的lib下,NSData的可能會發生變化,所以兩種方法的工作不同,它不能解密在IOS5加密文件。

在我的基於IOS6的代碼中,我在我的課程中編寫了方法。 是這樣的:

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

這段代碼和IOS5一樣工作得很好。

0

你需要給你如何實現你的加密,你用什麼特別選項的詳細信息。

根據我的經驗,iOS 6上解密失敗的最常見原因是他們更改/修復的CTR錯誤。在iOS 5中,有一個選項kCCModeOptionCTR_LE這是一個謊言。它實際上用kCCModeOptionCTR_BE加密。在iOS 6中,他們解決了這個問題,如果你嘗試使用kCCModeOptionCTR_LE,你會得到一個「未實現」的錯誤。但CCCrypt()通常不使用CTR模式,所以我不知道這是否適用。

+0

Rob謝謝,我粘貼了代碼,不使用'kCCModeOptionCTR_LE' – gordon