Search code examples
iosencryption3descbc-mode

ios 3DES encryption/decryption CBC


I need some help with this 3DES decryption. I have created some code for decryption but i cant get it to work as it should.This is the first time i am playing around with encryptions and i don't know what exactly am i doing wrong here.

I am receiving the key for the decryption from server (this is example value for the key: 0F7BC98767FF9A01F2B2AD1CD644AD33 - it is hex representation of random generated bytes).

this is the method that I use to decrypt the message:

-(NSString*)doCipher:(NSString*)message key:(NSString*)key operation:(CCOperation)encryptOrDecrypt {

const void *messageData;
size_t messageBufferSize;

if (encryptOrDecrypt == kCCDecrypt){
    NSData *messageEncryptData= [NSData dataWithBase64EncodedString:message];
    messageBufferSize= [messageEncryptData length];
    messageData= [messageEncryptData bytes];
}
else{
    messageBufferSize= message.length;
    messageData = [[[message dataUsingEncoding: NSUTF8StringEncoding]mutableCopy] bytes];
}

CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;

bufferPtrSize = (messageBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);

uint8_t iv[kCCBlockSize3DES];
memset((void *) iv, 0x0, (size_t) sizeof(iv));



NSData *keyData = [[key dataUsingEncoding:NSUTF8StringEncoding]mutableCopy];

ccStatus = CCCrypt(encryptOrDecrypt,
                   kCCAlgorithm3DES,
                   kCCOptionPKCS7Padding & kCCModeCBC,
                   (const void *)[keyData bytes],
                   kCCKeySize3DES,
                   iv,
                   messageData,
                   messageBufferSize,
                   (void *)bufferPtr,
                   bufferPtrSize,
                   &movedBytes);

if (ccStatus == kCCParamError) return @"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";

NSLog(@"bufferPtr: %s", bufferPtr);

NSString *s = [[NSString alloc] initWithFormat:@"%s", bufferPtr];
return s;
}

-- EDIT --- this is output that I receive from the method:

bufferPtr: Ã’ ÕÏÁU

--- EDIT 2 ----- I fixed the key length to be 24 byte long, but now the end result is empty string


Solution

  • i Found my problem. It was the way i was reading the key.

    i created this method for converting hex string into NSData:

    + (NSData *)dataFromHexString: (NSString *) hex {
    const char *chars = [hex UTF8String];
    int i = 0, len = hex.length;
    
    NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
    char byteChars[3] = {'\0','\0','\0'};
    unsigned long wholeByte;
    
    while (i < len) {
        byteChars[0] = chars[i++];
        byteChars[1] = chars[i++];
        wholeByte = strtoul(byteChars, NULL, 16);
        [data appendBytes:&wholeByte length:1];
    }
    
    return data;
    }
    

    then this is how i managed to decrypt the damn thing:

    NSData *keyData = [Utilities dataFromHexString:key];
    
    ccStatus = CCCrypt(encryptOrDecrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding,
                       [keyData bytes],
                       [keyData length],
                       iv,
                       messageData,
                       messageBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);
    

    Sorry for wasting your time :)