Question

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???

Was it helpful?

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top