Kasper Cottaar
Kasper Cottaar

Reputation: 462

3DES encryption in iOS does not seem to encrypt last block

I have the following code in objective-c

NSString* v_plainText = @"1234567890123456789012345678";
NSString* plainText = (const void *) [v_plainText UTF8String];

size_t plainTextBufferSize = [v_plainText length];

size_t bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
size_t movedBytes = 0;
uint8_t *bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));

Byte iv[8] = {0,0,0,0,0,0,0,0};

NSString *key = (const void *) [@"12345678ABCDEFGH!@#$%^&*" UTF8String];

CCCryptorStatus ccStatus;
ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithm3DES,
                   kCCOptionPKCS7Padding & kCCModeCBC,
                   key,
                   kCCKeySize3DES,
                   iv,
                   plainText,
                   plainTextBufferSize,
                   (void *)bufferPtr, // output
                   bufferPtrSize,
                   &movedBytes);

NSData* result = [NSData dataWithBytes:(const void*)bufferPtr length:(NSUInteger)movedBytes];
NSString* str = [result base64EncodedStringWithOptions:0];

This gives this result:

geHFnvoept2aKiruo6InSvc7WVPdHNq2

When I run simular code in .NET it gives me this result:

geHFnvoept2aKiruo6InSvc7WVPdHNq2TENQX5q9Beg=

For some reason the objective-c version only returns 24 bytes while the input is 28 bytes. I would expect it to be 32 bytes like in the .NET version. I was unable to determine what I'm doing wrong here.

Upvotes: 1

Views: 167

Answers (1)

zaph
zaph

Reputation: 112857

The encryption error is:

kCCOptionPKCS7Padding & kCCModeCBC,

You need |, not & but kCCModeCBC is not a valid option and no option is needed because CBC is the default mode, you simply need:

kCCOptionPKCS7Padding,

Unfortunatly there are other objectiveC coding errors, mainly:

NSString* plainText = (const void *) [v_plainText UTF8String];
NSString *key = (const void *) [@"12345678ABCDEFGH!@#$%^&*" UTF8String];

Instead use:

NSData* plainText = [v_plainText dataUsingEncoding:NSUTF8StringEncoding];
NSData *key = [@"12345678ABCDEFGH!@#$%^&*" dataUsingEncoding:NSUTF8StringEncoding];

Here is the complete code converted to use NSData:

NSString* plainText = @"1234567890123456789012345678";
NSString* keyText = @"12345678ABCDEFGH!@#$%^&*";

NSData* plainData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [keyText dataUsingEncoding:NSUTF8StringEncoding];
Byte iv[8] = {0,0,0,0,0,0,0,0};
size_t bufferSize = plainData.length + kCCBlockSize3DES;
NSMutableData *cypherData = [NSMutableData dataWithLength:bufferSize];
size_t movedBytes = 0;

CCCryptorStatus ccStatus;
ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithm3DES,
                   kCCOptionPKCS7Padding,
                   keyData.bytes,
                   kCCKeySize3DES,
                   iv,
                   plainData.bytes,
                   plainData.length,
                   cypherData.mutableBytes,
                   cypherData.length,
                   &movedBytes);

cypherData.length = movedBytes;
NSString* str = [cypherData base64EncodedStringWithOptions:0];
NSLog(@"str: %@", str);

Oputput:

str: geHFnvoept2aKiruo6InSvc7WVPdHNq2TENQX5q9Beg=

Upvotes: 2

Related Questions