Search code examples
objective-c3des

encrypt nsstring with 3des ios7


I am new with iOS7 development and objective c, and i need to develop an application which will send encrypted data with 3DES to a server,I have searched in stack overflow and Net but still unable to get it work, finally i tried this code but i got null as result,

+ (NSString*)encrypt:(NSString*)plainText withKey:(NSString*)key{
    uint8_t keyByte[kSecrectKeyLength];

    NSMutableData *keyData = [[NSMutableData alloc] init];
    int i;
    for (i=0; i < [key length] / 2; i++) {
        NSString *tempNumber = [key substringWithRange: NSMakeRange(i * 2, 2)];
        NSScanner *scanner=[NSScanner scannerWithString:tempNumber];
        unsigned int temp;
        [scanner scanHexInt:&temp];
        Byte B = (Byte)(0xFF & temp);
        keyByte[i] = B;
    }

    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    size_t plainTextBufferSize = [data length];
    const void *vplainText = (const void *)[data bytes];

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

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

    const void *vkey = (const void *) keyByte;
    const void *vinitVec = (const void *) [gIv UTF8String];

    ccStatus = CCCrypt(kCCEncrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding,
                       vkey,
                       kCCKeySize3DES,
                       vinitVec,
                       vplainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);

    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
    //NSString *result = [GTMBase64 stringByEncodingData:myData];
    NSString *result = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];

    NSLog(@"result=%@",result);

    return result;
}

Please have u any idea about the solution???


Solution

  • lol i just struggled with this myself the other day, i have a working solution now using this code

    + (NSData *)tripleDesEncryptString:(NSString *)input
                                   key:(NSString *)key
                                 error:(NSError **)error
    {
    NSParameterAssert(input);
    NSParameterAssert(key);
    
    NSData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding];
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    
    size_t outLength;
    
    NSAssert(keyData.length == kCCKeySize3DES, @"the keyData is an invalid size");
    
    NSMutableData *outputData = [NSMutableData dataWithLength:(inputData.length  +  kCCBlockSize3DES)];
    
    CCCryptorStatus
    result = CCCrypt(kCCEncrypt, // operation
                     kCCAlgorithm3DES, // Algorithm
                     kCCOptionPKCS7Padding | kCCOptionECBMode, // options
                     keyData.bytes, // key
                     keyData.length, // keylength
                     nil,// iv
                     inputData.bytes, // dataIn
                     inputData.length, // dataInLength,
                     outputData.mutableBytes, // dataOut
                     outputData.length, // dataOutAvailable
                     &outLength); // dataOutMoved
    
    if (result != kCCSuccess) {
        if (error != NULL) {
            *error = [NSError errorWithDomain:@"com.your_domain.your_project_name.your_class_name."
                                         code:result
                                     userInfo:nil];
        }
        return nil;
    }
    [outputData setLength:outLength];
    return outputData;
    }
    
    
    
    + (NSString *)tripleDesDecryptData:(NSData *)input
                                   key:(NSString *)key
                                 error:(NSError **)error
    {
    NSParameterAssert(input);
    NSParameterAssert(key);
    
    NSData *inputData = input;
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    
    size_t outLength;
    
    NSAssert(keyData.length == kCCKeySize3DES, @"the keyData is an invalid size");
    
    NSMutableData *outputData = [NSMutableData dataWithLength:(inputData.length  +  kCCBlockSize3DES)];
    
    CCCryptorStatus
    result = CCCrypt(kCCDecrypt, // operation
                     kCCAlgorithm3DES, // Algorithm
                     kCCOptionPKCS7Padding | kCCOptionECBMode, // options
                     keyData.bytes, // key
                     keyData.length, // keylength
                     nil,// iv
                     inputData.bytes, // dataIn
                     inputData.length, // dataInLength,
                     outputData.mutableBytes, // dataOut
                     outputData.length, // dataOutAvailable
                     &outLength); // dataOutMoved
    
    if (result != kCCSuccess) {
        if (error != NULL) {
            *error = [NSError errorWithDomain:@"com.your_domain.your_project_name.your_class_name."
                                         code:result
                                     userInfo:nil];
        }
        return nil;
    }
    [outputData setLength:outLength];
    return [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding];
    }
    

    you probably want to base64 encode the data the comes out of the encryption method, and then un-base64 anything that you want to decrypt as well, there are built in methods for NSData to do this now, eg:

    [data base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)];
    

    to test if the functions work, i used this test function

    + (void) testEncryptionAndDecryption {
    
        NSData *encrypted = [self tripleDesEncryptString:@"test" key:@"123456789123456789123456" error:nil];
        NSLog(@"encrypted data length: %lu", (unsigned long)encrypted.length);
        NSString *decrypted = [self tripleDesDecryptData:encrypted key:@"123456789123456789123456" error:nil];
        NSLog(@"decrypted text: %@", decrypted);
    }
    

    this gave me the correct output that you would expect