AES-128 Decryption in Objective-C just slightly off I have been asked to integrate a home-grown CRM system with a 3rd-party data service provider (DSP).  The DSP has encrypted the information they are providing.  I only have their decryption instructions, which are as follows (verbatim):

Encryption Type: AES128
Mode: CBC
Padding: PKCS5 (.net usesPKCS7)
Password: jayjay
Encryption reference:(link below)


decryption example as provided by the DSP

The DSP instructions also contain some sample data, namely:

Sample Encrypted data:

h6KlotyqYvipjQHICwJK25mqY+2GC6qc/qf5fCBoGYaxe2zQad/j6Dxo6H259PretcjkUcBsgMl+vFkYPXGwH vbZMqMPCIznBrdZeSWP+Hie7YdLRYp9V5/JKLTIZZlZAG7Vii8DepV5KXjbat4qGxNTVRAvDQ8tT9xZbzEbzY 7Sb9q/f9TE/yardrrgDntw9WywTDbU4Yfg3BEC0jIKFg==


Sample Expected Decrypted data:

123456^CustIDLookup^John^Doe^Placeholder Name^ATS^217 General Patton Ave.^Suite 208^Mandeville^LA^70471^United States^985-809-0600^postmaster@atsleads.com


So, my mission, should I choose to accept it, is to arrive at the decrypted example.  This is for use within a native iOS app, so I need to code the decryption in Objective-C.

So far, my results for the decrypted data NSString look like this:

__NSCFString *  @"(\0\x1d\r\x040D^CustIDLookup^First Name^Last Name^Title^Company^Address 1^Address 2^City^State^Zip^Country^Phone^Email"   0x00000001780ee700


i.e. I am getting this result string:

\0\x1d\r\x040D^CustIDLookup^First Name^Last Name^Title^Company^Address 1^Address 2^City^State^Zip^Country^Phone^Email


I have shown my code below.  I can get very close to the expected decryption, but I can't match it exactly - the first 5 chars are wrong.  

Can anyone shed any light on this issue, and perhaps steer me in a direction that would allow my decryption code to decipher the data correctly?  I'm no expert on encryption, but it seems strange to me that I'm very close but am not yet enjoying my cigar.  In my reading so far I have seen comments stating that AES128 and PKCS5 don't make sense together, but I don't if this has any bearing on things.

I have coded an NSMutableData category (extension) as follows: 

@implementation NSMutableData (AES)

- (NSMutableData*)DecryptAES: (NSString*)key
{
    int blockSize = 16; // Actually kCCKeySizeAES128, but hard-coded for experimentation
    char  keyPtr[blockSize];
    bzero( keyPtr, sizeof(keyPtr) );
    bool rc1 = [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    if (rc1==NO){
        NSLog(@"getCString failed");
    }

    size_t numBytesEncrypted = 0;
    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + blockSize;
    void *buffer_decrypt = malloc(bufferSize);
    NSMutableData *output_decrypt = [[NSMutableData alloc] init];
    char ivBytes[8] = {0,0,0,0,0,0,0,kCCModeCBC};
    //char ivBytes[8] = {0,0,0,0,0,0,0,0}; // same results with this line
    int ivLength = sizeof(ivBytes);
    NSData* initialisationVector = [[NSData alloc] initWithBytes:ivBytes length:ivLength];

    //CCCryptorStatus result = CCCrypt(operation, algo, optarg, key, keylength, iv, datain, datainlength, dataout, dataoutavailable, dataoutmoved)
    CCCryptorStatus result = CCCrypt(kCCDecrypt , kCCAlgorithmAES, kCCOptionPKCS7Padding , keyPtr, blockSize, initialisationVector.bytes, [self mutableBytes], [self length], buffer_decrypt, bufferSize, &amp;numBytesEncrypted);

    if (result!=kCCSuccess){
        NSLog(@"CCCrypt did not work");
    }

    output_decrypt = [NSMutableData dataWithBytesNoCopy:buffer_decrypt length:numBytesEncrypted];

    if(result == kCCSuccess) {
        return output_decrypt;
    }
    return NULL;

}

@end


I am then calling this category as follows:

NSMutableData* originalStringAsData = [[NSMutableData alloc] initWithBase64EncodedString:self.originalString options:nil];

NSMutableData* decryptedData  = [originalStringAsData DecryptAES:@"jayjay"];

NSString* decryptedString1 = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];


Any help would be hugely appreciated.
When you get the first part of the decryption wrong, but the rest correct, it almost always means that you got the IV wrong.

However, with CBC mode, what usually happens is that you get the first 16 bytes wrong; instead, you got only 6 bytes wrong; that may indicate that you got the first 6 bytes of the IV wrong (and the other 10 bytes correct).

In addition, I notice that, in your code, you're handing an 8 byte IV to the API; this is odd, because CBC mode takes a 16 byte IV.

I don't know the API you're using (and I certainly don't know the assumptions that the DSP has used), and so I'm at a loss at helping you any further -- however, you were looking for suggestions as to where to look...