CCCrypt encrypted using ios5 cannot be decrypted using ios6

My cocos2d game saves data using CCCrypt () encryption. I use the MAC address as the encryption key. A save file encrypted in iOS5 cannot decrypt with the same mac address in iOS6. This means that a user who has updated his game will lose all his data!

Is it possible to decrypt the old file?

Here is the code:

@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 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 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 
+6
source share
2 answers

Ok, I found a solution.

Key points:

I am adding two methods to NSData for encryption and decryption using IOS5 lib based on code.

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

Now in IOS6 lib NSData can be changed, so the two methods work differently, it can not decrypt file encryption in IOS5.

In my IOS6 based code, I wrote methods in my class. eg:

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

The code works the same as in iOS5.

-3
source

You will need to talk in detail about how you implemented your encryption, in particular, what parameters you used.

The most common cause of unsuccessful decrypts on iOS 6 in my experience is the CTR error that they changed / fixed. In iOS 5, there was the kCCModeOptionCTR_LE option, which was a lie. It is actually encrypted using kCCModeOptionCTR_BE . In iOS 6, they fixed it, and if you try to use kCCModeOptionCTR_LE , you will get an "unimplemented" error message. But CCCrypt () usually does not use CTR mode, so I do not know if this is applicable.

0
source

All Articles