Well, I managed to solve this with a lot of reading and comments here on stackoverflow. Where a few questions. The key I gave the .NET developers was 48 characters. This, of course, had to be read as the sixth line and converted to 24 characters.
I added code to do this, and the full procedure is as follows. I am not sure if this will be useful, as it is very specific to our implementation.
+ (NSString *)doCipher3DES:(NSString *)sTextIn key:(NSString *)sKey { NSMutableData * dTextIn; CCCryptorStatus ccStatus = kCCSuccess; // need to add 4 zeros as sTextIn will be a 4 digit PIN sTextIn = [sTextIn stringByAppendingString:@"0000"]; // convert to data dTextIn = [[sTextIn dataUsingEncoding: NSASCIIStringEncoding] mutableCopy]; // key will be a 48 char hex stream, so process it down to 24 chars const char * bytes = [sKey cStringUsingEncoding: NSUTF8StringEncoding]; NSUInteger length = strlen(bytes); unsigned char * r = (unsigned char *) malloc(length / 2 + 1); unsigned char * index = r; while ((*bytes) && (*(bytes +1))) { *index = strToChar(*bytes, *(bytes +1)); index++; bytes+=2; } *index = '\0'; NSData *dKey = [NSData dataWithBytes: r length: length / 2]; free(r); NSLog(@"doCipher3DES - key: %@", dKey); uint8_t *bufferPtr1 = NULL; size_t bufferPtrSize1 = 0; size_t movedBytes1 = 0; uint8_t iv[kCCBlockSize3DES]; memset((void *) iv, 0x0, (size_t) sizeof(iv)); bufferPtrSize1 = ([sTextIn length] + kCCBlockSize3DES) & ~(kCCBlockSize3DES -1); bufferPtr1 = malloc(bufferPtrSize1 * sizeof(uint8_t)); memset((void *)bufferPtr1, 0x00, bufferPtrSize1); ccStatus = CCCrypt(kCCEncrypt, // CCOperation op kCCAlgorithm3DES, // CCAlgorithm alg kCCOptionECBMode, // CCOptions options (const void *)[dKey bytes], // const void *key kCCKeySize3DES, // size_t keyLength nil, // const void *iv (const void *)[dTextIn bytes], // const void *dataIn [dTextIn length], // size_t dataInLength (void *)bufferPtr1, // void *dataOut bufferPtrSize1, // size_t dataOutAvailable &movedBytes1); // size_t *dataOutMoved if (ccStatus == kCCParamError) NSLog(@"PARAM ERROR"); else if (ccStatus == kCCBufferTooSmall) NSLog(@"BUFFER TOO SMALL"); else if (ccStatus == kCCMemoryFailure) NSLog(@"MEMORY FAILURE"); else if (ccStatus == kCCAlignmentError) NSLog(@"ALIGNMENT"); else if (ccStatus == kCCDecodeError) NSLog(@"DECODE ERROR"); else if (ccStatus == kCCUnimplemented) NSLog(@"UNIMPLEMENTED"); NSString * sResult; NSData *dResult = [NSData dataWithBytes:bufferPtr1 length:movedBytes1]; NSLog(@"doCipher3DES encrypted: %@", dResult); sResult = [Base64 encode:dResult]; return sResult; }
The code for strToChar is as follows:
unsigned char strToChar (char a, char b) { char encoder[3] = {'\0','\0','\0'}; encoder[0] = a; encoder[1] = b; return (char) strtol(encoder,NULL,16); }
I hope this helps someone ...
Russell Hill
source share