3

I am trying to decrypt data from a .NET server in an iOS application. The data has been encrypted with 3DES in ECB mode. I was able to successfully decrypt this same data on Android, but on IOS I just keep getting garbage output.

I've compared the encrypted bytes and digested key bytes between iOS and Android and they appear to be the same (although I had to convert the signed Java bytes into a hex representation to be able to compare to xcode debugger). However, the Java crypto objects` are higher level than Common Crypto, so I'm not confident that I've prepared the key correctly. Please take a look at the following code - any feedback is welcome.

//read the encrypted data from file into NSData
NSString *servicesPath = [NSString stringWithString:[[AppMobiDelegate applicationDocumentsDirectory] stringByAppendingPathComponent:@"services.xml"]];
NSData *servicesData = [NSData dataWithContentsOfFile:servicesPath];

//setup crypto objects
const void *vEncryptedText = [servicesData bytes];
size_t encryptedTextBufferSize = [servicesData length];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (encryptedTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);

//get a cstring with key data
const char *cStr = [@"FAKEKEY" cStringUsingEncoding:UTF8String];

//make a 16 byte array to put the md5 digested data into    
unsigned char md5[CC_MD5_DIGEST_LENGTH];
bzero( md5, sizeof(md5) );
CC_MD5( cStr, strlen(cStr), md5 );
//make a 24 byte array so we have correct size for 3des key and copy digest data in
unsigned char key[kCCKeySize3DES];
bzero( key, sizeof(key) );
memcpy(key, md5, sizeof(md5));  

//decrypt data and return string 
ccStatus = CCCrypt(kCCDecrypt,
    kCCAlgorithm3DES,
    kCCOptionECBMode, //kCCOptionPKCS7Padding kCCOptionECBMode
    key, //vKey md5
    kCCKeySize3DES,
    NULL,
    vEncryptedText,
    encryptedTextBufferSize,
    (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";

NSString *result = [[[NSString alloc] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding] autorelease];
return result;
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
ajh158
  • 1,477
  • 1
  • 13
  • 32
  • Did you solve problem ? I'm facing the same – kinghomer Sep 27 '12 at 10:01
  • Yes, but if I recall correctly, it was not straightforward and additional changes were needed on both the iOS side and the .NET side. – ajh158 Oct 02 '12 at 12:23
  • Which are these changes? Take a look here pls. Maybe you can help me: http://stackoverflow.com/questions/12607937/3des-result-in-java-produces-different-result-from-3des-ios-version#comment17160746_12607937 – kinghomer Oct 03 '12 at 15:25
  • Can you post NET and/or iOS code pls ? – kinghomer Oct 23 '12 at 13:03
  • 1
    Slightly OT and _slightly_ late to the party, but I hope you are not protecting anything serious with 3DES-ECB. 3DES per se is not really broken, but its small block size (64bits) and the fact that you are using it in ECB mode make it very easy to spot recurrent patterns in the input and even manipulate it at block level (deletion, insertion and recombination of blocks are all possible). – Stefano Sanfilippo Feb 25 '15 at 00:07

0 Answers0