objective-cencryptionaesencryption-symmetric

CCCrypt encryption result issue


I'm using CCCrypt for encryption/decryption string values. It seems to work fine, because decrypted value equals initial one, but the problem is I can't extract proper NSString object from decrypted data.

@implementation NSData (AES256) 

- (NSData *)AES256EncryptWithKey:(NSString *)key 
{
    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];

    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) { 
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }

    free(buffer); //free the buffer;
    return nil;
}

- (NSData *)AES256DecryptWithKey:(NSString *)key {
    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];

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

I can't get what is done wrong so if anyone can help, I'll highly appreciate that.

And the second part of question - how can I set the CBC mode for AES encryption method. It's said in documentation that this mode is used by default but what should I pass as the third argument in CCCrypt method?


Solution

  • Addressing the question you commented in the previous answer, the initWithData:encoding: function will return nil because the encrypted data is very unlikely to match up with NSUTF8StringEncoding, given the fact that it is encrypted.

    Same question with thorough answer: Why does my initWithData return nil indicating an error after converting NSData to NSString returning from encrypting via CommonCrypto? though as an aside, base64 does not make your encrypted data a visible string, but rather alters it further to make a displayable ASCII string. This string shouldn't be assumed to be the same as the encrypted data nor the same as encrypting the data, but for use as a string, such as in a keychain, it works just fine.