2

I have some serious trouble with a CommonCrypto function. There are two existing applications for BlackBerry and Windows Mobile, both use Triple-DES encryption with ECB mode for data exchange. On either the encrypted results are the same.

Now I want to implent the 3DES encryption into our iPhone application, so I went straight for CommonCrypto: http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-32207/CommonCrypto/CommonCryptor.h

I get some results if I use CBC mode, but they do not correspond with the results of Java or C#. Anyway, I want to use ECB mode, but I don't get this working at all - there is a parameter error showing up...

This is my call for the ECB mode... I stripped it a little bit:

const void *vplainText;

plainTextBufferSize = [@"Hello World!" length];
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);

plainText = (const void *) [@"Hello World!" UTF8String];
NSString *key = @"abcdeabcdeabcdeabcdeabcd";

ccStatus = CCCrypt(kCCEncrypt,
     kCCAlgorithm3DES,
     kCCOptionECBMode,
     key,
     kCCKeySize3DES,
     nil, // iv, not used with ECB
     plainText,
     plainTextBufferSize,
     (void *)bufferPtr, // output
     bufferPtrSize,
     &movedBytes);

t is more or less the code from here: http://discussions.apple.com/thread.jspa?messageID=9017515 But as already mentioned, I get a parameter error each time...

When I use kCCOptionPKCS7Padding instead of kCCOptionECBMode and set the same initialization vector in C# and my iPhone code, the iPhone gives me different results. Is there a mistake by getting my output from the bufferPtr? Currently I get the encrypted stuff this way:

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

It seems I almost tried every setting twice, different encodings and so on... where is my error?

Jan Gressmann
  • 5,481
  • 4
  • 32
  • 26

3 Answers3

1

Can you post the error message?

One of the best ways to troubleshoot this stuff, I've found, is to take known input, known key and known output ("test vectors") and compare the bytes of the expected output with the observed output.

What you're doing here is probably not a good way to test the output:

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

How do you know the encrypted binary data can be interpreted with the NSISOLatin1StringEncoding encoding?

Instead, compare the bytes directly (via [myData description] or the like) or translate the output with hexadecimal or base64 encoding.

Community
  • 1
  • 1
Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
  • Thanks for the tip, I managed to get it up and running with kCCOptionPKCS7Padding (read: CBC mode). It seems the encoding of the output was the problem. I'll use this instead the ECB mode, but I'm still curious why I get the error - the function just returns a kCCParamError if kCCOptionECBMode is used. – Jan Gressmann Sep 08 '09 at 11:15
1

I believe the problem is that kCCOptionECBMode alone is not enough. You also need padding (since it is a block cypher). If you pass both (i.e. kCCOptionPKCS7Padding | kCCOptionECBMode ) it will work.

honus
  • 799
  • 6
  • 14
0

I realise this is an old question, but for reference, I think that your key should not be passed in as an NSString. The key should instead be converted from hexadecimal to a byte array. This hexToBytes NSString extension should provide what you need by doing the following:

[[key hexToBytes] bytes]

The key should also be twice as long as the one given (48 characters of hex, i.e. 24 bytes).

Community
  • 1
  • 1
Luke Rogers
  • 2,369
  • 21
  • 28